WordPress.org

Make WordPress Core

Ticket #37667: 37667.3.diff

File 37667.3.diff, 22.0 KB (added by flixos90, 5 years ago)
  • src/wp-includes/class-wp-post-type.php

     
    325325        public $rewrite;
    326326
    327327        /**
    328          * The features supported by the post type.
     328         * The features supported by the post type, per post type definition.
    329329         *
    330330         * @since 4.6.0
    331331         * @access public
     
    334334        public $supports;
    335335
    336336        /**
     337         * All features supported by the post type.
     338         *
     339         * @since 4.7.0
     340         * @access private
     341         * @var array $features
     342         */
     343        private $features = array();
     344
     345        /**
     346         * A list of early post type features.
     347         *
     348         * @since 4.7.0
     349         * @access private
     350         * @static
     351         * @var array
     352         */
     353        private static $early_features = array();
     354
     355        /**
    337356         * Constructor.
    338357         *
    339358         * Will populate object properties from the provided arguments and assign other
     
    351370        public function __construct( $post_type, $args = array() ) {
    352371                $this->name = $post_type;
    353372
     373                if ( ! empty( self::$early_features[ $this->name ] ) ) {
     374                        $this->features = self::$early_features[ $this->name ];
     375                        unset( self::$early_features[ $this->name ] );
     376                }
     377
    354378                $this->set_props( $args );
    355379        }
    356380
     
    511535         */
    512536        public function add_supports() {
    513537                if ( ! empty( $this->supports ) ) {
    514                         add_post_type_support( $this->name, $this->supports );
     538                        $this->add_support( $this->supports );
    515539                        unset( $this->supports );
    516540                } elseif ( false !== $this->supports ) {
    517541                        // Add default features.
    518                         add_post_type_support( $this->name, array( 'title', 'editor' ) );
     542                        $this->add_support( array( 'title', 'editor' ) );
    519543                }
    520544        }
    521545
     
    602626        }
    603627
    604628        /**
     629         * Registers support of certain features for the post type.
     630         *
     631         * All core features are directly associated with a functional area of the edit
     632         * screen, such as the editor or a meta box. Features include: 'title', 'editor',
     633         * 'comments', 'revisions', 'trackbacks', 'author', 'excerpt', 'page-attributes',
     634         * 'thumbnail', 'custom-fields', and 'post-formats'.
     635         *
     636         * Additionally, the 'revisions' feature dictates whether the post type will
     637         * store revisions, and the 'comments' feature dictates whether the comments
     638         * count will show on the edit screen.
     639         *
     640         * @since 4.7.0
     641         * @access public
     642         *
     643         * @param string|array $feature The feature being added, accepts an array of
     644         *                              feature strings or a single string.
     645         * @param bool         $value   Optional. The value to give to the feature. Default
     646         *                              true.
     647         * @param string       $subtype Optional. A subtype to add this feature to. An
     648         *                              empty value will add this feature to the overall
     649         *                              post type. Default empty.
     650         */
     651        public function add_support( $feature, $value = true, $subtype = '' ) {
     652                $features = (array) $feature;
     653                foreach ( $features as $feature ) {
     654                        $this->features[ $subtype ][ $feature ] = $value;
     655                }
     656        }
     657
     658        /**
     659         * Removes support for a feature from the post type.
     660         *
     661         * @since 4.7.0
     662         * @access public
     663         *
     664         * @param string $feature The feature being removed.
     665         * @param string $subtype Optional. A subtype to remove this feature from. An
     666         *                        empty value will remove this feature from the overall
     667         *                        post type. Default empty.
     668         */
     669        public function remove_support( $feature, $subtype = '' ) {
     670                unset( $this->features[ $subtype ][ $feature ] );
     671        }
     672
     673        /**
     674         * Gets all the post type features.
     675         *
     676         * @since 4.7.0
     677         * @access public
     678         *
     679         * @param string $subtype Optional. A subtype to get its features. An
     680         *                        empty value will return the overall post type
     681         *                        features. Default empty.
     682         * @return array Post type supports list.
     683         */
     684        public function get_all_supports( $subtype = '' ) {
     685                return $this->features[ $subtype ];
     686        }
     687
     688        /**
     689         * Checks the post type's support for a given feature.
     690         *
     691         * @since 4.7.0
     692         * @access public
     693         *
     694         * @param string $feature The feature being checked.
     695         * @param string $subtype Optional. A subtype to check in its features. An
     696         *                        empty value will check within the overall post type
     697         *                        features. Default empty.
     698         * @return bool Whether the post type supports the given feature.
     699         */
     700        public function supports( $feature, $subtype = '' ) {
     701                return isset( $this->features[ $subtype ][ $feature ] );
     702        }
     703
     704        /**
     705         * Retrieves a list of post type and subtype names that support a specific feature.
     706         *
     707         * If the features are supported by the overall post type, the post type name is
     708         * included in the list. If the features are supported by a specific subtype, a
     709         * string consisting of post type name and subtype name delimited by a colon is
     710         * included in the list.
     711         *
     712         * @since 4.7.0
     713         * @access public
     714         *
     715         * @param array|string $feature  Single feature or an array of features the post type should support.
     716         * @param string       $operator Optional. The logical operation to perform. 'or' means
     717         *                               only one element from the array needs to match; 'and'
     718         *                               means all elements must match; 'not' means no elements may
     719         *                               match. Default 'and'.
     720         * @return array A list of post type and subtype names.
     721         */
     722        public function get_by_support( $feature, $operator = 'and' ) {
     723                $features = array_fill_keys( (array) $feature, true );
     724                $subtypes = array_keys( wp_filter_object_list( $this->features, $features, $operator ) );
     725
     726                $names = array();
     727                foreach ( $subtypes as $subtype ) {
     728                        if ( empty( $subtype ) ) {
     729                                $names[] = $this->name;
     730                        } else {
     731                                $names[] = $this->name . ':' . $subtype;
     732                        }
     733                }
     734
     735                return $names;
     736        }
     737
     738        /**
    605739         * Removes the features support for the post type.
    606740         *
    607741         * @since 4.6.0
    608742         * @access public
    609          *
    610          * @global array $_wp_post_type_features Post type features.
    611743         */
    612744        public function remove_supports() {
    613                 global $_wp_post_type_features;
    614 
    615                 unset( $_wp_post_type_features[ $this->name ] );
     745                $this->features = array();
    616746        }
    617747
    618748        /**
     
    683813        public function remove_hooks() {
    684814                remove_action( 'future_' . $this->name, '_future_post_hook', 5 );
    685815        }
     816
     817        /**
     818         * Registers support of certain features for a post type early.
     819         *
     820         * The feature is added just-in-time when add_post_type_support() is called for
     821         * a $post_type before it has been registered.
     822         *
     823         * @since 4.7.0
     824         * @access public
     825         * @static
     826         * @ignore
     827         *
     828         * @see add_post_type_support()
     829         *
     830         * @param string       $post_type The post type for which to add the feature.
     831         * @param string|array $feature   The feature being added, accepts an array of
     832         *                                feature strings or a single string.
     833         * @param bool         $value     Optional. The value to give to the feature. Default
     834         *                                true.
     835         * @param string       $subtype   Optional. A subtype to add this feature to. An
     836         *                                empty value will add this feature to the overall
     837         *                                post type. Default empty.
     838         */
     839        public static function add_support_early( $post_type, $feature, $value, $subtype = '' ) {
     840                self::$early_features[ $post_type ][ $subtype ][ $feature ] = $value;
     841        }
     842
     843        /**
     844         * Removes support for a feature from a post type early.
     845         *
     846         * The feature is removed just-in-time when remove_post_type_support() is called for
     847         * a $post_type before it has been registered.
     848         *
     849         * @since 4.7.0
     850         * @access public
     851         * @static
     852         * @ignore
     853         *
     854         * @see remove_post_type_support()
     855         *
     856         * @param string $post_type The post type for which to remove the feature.
     857         * @param string $feature   The feature being removed.
     858         * @param string $subtype   Optional. A subtype to remove this feature from. An
     859         *                          empty value will remove this feature from the overall
     860         *                          post type. Default empty.
     861         */
     862        public static function remove_support_early( $post_type, $feature, $subtype = '' ) {
     863                if ( ! isset( self::$early_features[ $post_type ][ $subtype ][ $feature ] ) ) {
     864                        return;
     865                }
     866
     867                unset( self::$early_features[ $post_type ][ $subtype ][ $feature ] );
     868        }
     869
     870        /**
     871         * Returns the list early post type features.
     872         *
     873         * @since 4.7.0
     874         * @access public
     875         * @static
     876         * @ignore
     877         *
     878         * @return array List of early post type features.
     879         */
     880        public static function get_early_support() {
     881                return self::$early_features;
     882        }
    686883}
  • src/wp-includes/post.php

     
    14841484 * count will show on the edit screen.
    14851485 *
    14861486 * @since 3.0.0
    1487  *
    1488  * @global array $_wp_post_type_features
     1487 * @since 4.7.0 Uses `WP_Post_Type` to handle features.
    14891488 *
    14901489 * @param string       $post_type The post type for which to add the feature.
    14911490 * @param string|array $feature   The feature being added, accepts an array of
    14921491 *                                feature strings or a single string.
    14931492 */
    14941493function add_post_type_support( $post_type, $feature ) {
    1495         global $_wp_post_type_features;
     1494        $subtype = '';
     1495        if ( strpos( $post_type, ':' ) ) {
     1496                list( $post_type, $subtype ) = explode( ':', $post_type );
     1497        }
     1498
     1499        if ( func_num_args() == 2 ) {
     1500                $value = true;
     1501        } else {
     1502                $value = array_slice( func_get_args(), 2 );
     1503        }
     1504
     1505        $ptype_obj = get_post_type_object( $post_type );
     1506        if ( ! $ptype_obj ) {
     1507                _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %s is not registered. Post type features should only be added to existing post types.' ), $post_type ), '4.7.0' );
    14961508
    1497         $features = (array) $feature;
    1498         foreach ($features as $feature) {
    1499                 if ( func_num_args() == 2 )
    1500                         $_wp_post_type_features[$post_type][$feature] = true;
    1501                 else
    1502                         $_wp_post_type_features[$post_type][$feature] = array_slice( func_get_args(), 2 );
     1509                WP_Post_Type::add_support_early( $post_type, $feature, $value, $subtype );
     1510                return;
    15031511        }
     1512
     1513        $ptype_obj->add_support( $feature, $value, $subtype );
    15041514}
    15051515
    15061516/**
    15071517 * Remove support for a feature from a post type.
    15081518 *
    15091519 * @since 3.0.0
    1510  *
    1511  * @global array $_wp_post_type_features
     1520 * @since 4.7.0 Uses `WP_Post_Type` to handle features.
    15121521 *
    15131522 * @param string $post_type The post type for which to remove the feature.
    15141523 * @param string $feature   The feature being removed.
    15151524 */
    15161525function remove_post_type_support( $post_type, $feature ) {
    1517         global $_wp_post_type_features;
     1526        $subtype = '';
     1527        if ( strpos( $post_type, ':' ) ) {
     1528                list( $post_type, $subtype ) = explode( ':', $post_type );
     1529        }
     1530
     1531        $ptype_obj = get_post_type_object( $post_type );
     1532        if ( ! $ptype_obj ) {
     1533                _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %s is not registered. Post type features should only be removed from existing post types.' ), $post_type ), '4.7.0' );
    15181534
    1519         unset( $_wp_post_type_features[ $post_type ][ $feature ] );
     1535                WP_Post_Type::remove_support_early( $post_type, $feature, $subtype );
     1536                return;
     1537        }
     1538
     1539        $ptype_obj->remove_support( $feature, $subtype );
    15201540}
    15211541
    15221542/**
    15231543 * Get all the post type features
    15241544 *
    15251545 * @since 3.4.0
    1526  *
    1527  * @global array $_wp_post_type_features
     1546 * @since 4.7.0 Uses `WP_Post_Type` to handle features.
    15281547 *
    15291548 * @param string $post_type The post type.
    15301549 * @return array Post type supports list.
    15311550 */
    15321551function get_all_post_type_supports( $post_type ) {
    1533         global $_wp_post_type_features;
     1552        $subtype = '';
     1553        if ( strpos( $post_type, ':' ) ) {
     1554                list( $post_type, $subtype ) = explode( ':', $post_type );
     1555        }
    15341556
    1535         if ( isset( $_wp_post_type_features[$post_type] ) )
    1536                 return $_wp_post_type_features[$post_type];
     1557        $ptype_obj = get_post_type_object( $post_type );
     1558        if ( ! $ptype_obj ) {
     1559                $post_type_features = WP_Post_Type::get_early_support();
     1560
     1561                if ( isset( $post_type_features[ $post_type ][ $subtype ] ) ) {
     1562                        return $post_type_features[ $post_type ][ $subtype ];
     1563                }
     1564                return array();
     1565        }
    15371566
    1538         return array();
     1567        return $ptype_obj->get_all_supports( $subtype );
    15391568}
    15401569
    15411570/**
    15421571 * Check a post type's support for a given feature.
    15431572 *
    15441573 * @since 3.0.0
    1545  *
    1546  * @global array $_wp_post_type_features
     1574 * @since 4.7.0 Uses `WP_Post_Type` to handle features.
    15471575 *
    15481576 * @param string $post_type The post type being checked.
    15491577 * @param string $feature   The feature being checked.
    15501578 * @return bool Whether the post type supports the given feature.
    15511579 */
    15521580function post_type_supports( $post_type, $feature ) {
    1553         global $_wp_post_type_features;
     1581        $subtype = '';
     1582        if ( strpos( $post_type, ':' ) ) {
     1583                list( $post_type, $subtype ) = explode( ':', $post_type );
     1584        }
     1585
     1586        $ptype_obj = get_post_type_object( $post_type );
     1587        if ( ! $ptype_obj ) {
     1588                $post_type_features = WP_Post_Type::get_early_support();
    15541589
    1555         return ( isset( $_wp_post_type_features[$post_type][$feature] ) );
     1590                return isset( $post_type_features[ $post_type ][ $subtype ][ $feature ] );
     1591        }
     1592
     1593        return $ptype_obj->supports( $feature, $subtype );
    15561594}
    15571595
    15581596/**
    15591597 * Retrieves a list of post type names that support a specific feature.
    15601598 *
    15611599 * @since 4.5.0
    1562  *
    1563  * @global array $_wp_post_type_features Post type features
     1600 * @since 4.7.0 Uses `WP_Post_Type` to handle features.
    15641601 *
    15651602 * @param array|string $feature  Single feature or an array of features the post types should support.
    15661603 * @param string       $operator Optional. The logical operation to perform. 'or' means
     
    15701607 * @return array A list of post type names.
    15711608 */
    15721609function get_post_types_by_support( $feature, $operator = 'and' ) {
    1573         global $_wp_post_type_features;
     1610        $names = array();
    15741611
    1575         $features = array_fill_keys( (array) $feature, true );
     1612        $ptype_objects = get_post_types( array(), 'objects' );
     1613        foreach ( $ptype_objects as $ptype_obj ) {
     1614                $names = array_merge( $names, $ptype_obj->get_by_support( $feature, $operator ) );
     1615        }
     1616
     1617        $post_type_features = WP_Post_Type::get_early_support();
     1618        if ( ! empty( $post_type_features ) ) {
     1619                $features = array_fill_keys( (array) $feature, true );
     1620
     1621                foreach ( $post_type_features as $post_type => $subtypes ) {
     1622                        $subtypes = array_keys( wp_filter_object_list( $subtypes, $features, $operator ) );
     1623                        foreach ( $subtypes as $subtype ) {
     1624                                if ( empty( $subtype ) ) {
     1625                                        $names[] = $post_type;
     1626                                } else {
     1627                                        $names[] = $post_type . ':' . $subtype;
     1628                                }
     1629                        }
     1630                }
     1631        }
    15761632
    1577         return array_keys( wp_filter_object_list( $_wp_post_type_features, $features, $operator ) );
     1633        return $names;
    15781634}
    15791635
    15801636/**
  • tests/phpunit/tests/post/typeSupport.php

     
     1<?php
     2
     3/**
     4 * @group post
     5 */
     6class Tests_Post_Type_Support extends WP_UnitTestCase {
     7
     8        /**
     9         * @ticket 37667
     10         */
     11        public function test_add_post_type_support_basic() {
     12                $post_type = rand_str( 20 );
     13                $feature = 'custom_feature_name';
     14
     15                register_post_type( $post_type );
     16                add_post_type_support( $post_type, $feature );
     17                $this->assertTrue( post_type_supports( $post_type, $feature ) );
     18        }
     19
     20        /**
     21         * @ticket 37667
     22         * @expectedIncorrectUsage add_post_type_support
     23         */
     24        public function test_add_post_type_support_unregistered_post_type() {
     25                $post_type = rand_str( 20 );
     26                $feature = 'custom_feature_name';
     27
     28                add_post_type_support( $post_type, $feature );
     29                $this->assertTrue( post_type_supports( $post_type, $feature ) );
     30        }
     31
     32        /**
     33         * @ticket 37667
     34         * @expectedIncorrectUsage add_post_type_support
     35         */
     36        public function test_add_post_type_support_before_register_post_type_after_registration() {
     37                $post_type = rand_str( 20 );
     38                $feature = 'custom_feature_name';
     39
     40                add_post_type_support( $post_type, $feature );
     41                register_post_type( $post_type );
     42                $this->assertTrue( post_type_supports( $post_type, $feature ) );
     43        }
     44
     45        /**
     46         * @ticket 37667
     47         */
     48        public function test_remove_post_type_support_basic() {
     49                $post_type = rand_str( 20 );
     50                $feature = 'editor';
     51
     52                register_post_type( $post_type );
     53                remove_post_type_support( $post_type, $feature );
     54                $this->assertFalse( post_type_supports( $post_type, $feature ) );
     55        }
     56
     57        /**
     58         * @ticket 37667
     59         * @expectedIncorrectUsage add_post_type_support
     60         * @expectedIncorrectUsage remove_post_type_support
     61         */
     62        public function test_remove_post_type_support_unregistered_post_type() {
     63                $post_type = rand_str( 20 );
     64                $feature = 'custom_feature_name';
     65
     66                add_post_type_support( $post_type, $feature );
     67                remove_post_type_support( $post_type, $feature );
     68                $this->assertFalse( post_type_supports( $post_type, $feature ) );
     69        }
     70
     71        /**
     72         * @ticket 37667
     73         * @expectedIncorrectUsage remove_post_type_support
     74         */
     75        public function test_remove_post_type_support_before_register_post_type() {
     76                $post_type = rand_str( 20 );
     77                $default_feature = 'editor';
     78
     79                // Features are added on post type registration, so removing them before shouldn't matter.
     80                remove_post_type_support( $post_type, $default_feature );
     81                register_post_type( $post_type );
     82                $this->assertTrue( post_type_supports( $post_type, $default_feature ) );
     83        }
     84
     85        /**
     86         * @ticket 37667
     87         * @expectedIncorrectUsage add_post_type_support
     88         */
     89        public function test_get_post_types_by_support_mixed() {
     90                $registered_post_type = rand_str( 20 );
     91                $unregistered_post_type = rand_str( 20 );
     92                $feature = 'unique_feature_name';
     93
     94                register_post_type( $registered_post_type );
     95
     96                add_post_type_support( $registered_post_type, $feature );
     97                add_post_type_support( $unregistered_post_type, $feature );
     98                $this->assertEqualSets( array( $registered_post_type, $unregistered_post_type ), get_post_types_by_support( $feature ) );
     99        }
     100}
  • tests/phpunit/tests/post/wpPostType.php

    Property changes on: tests/phpunit/tests/post/typeSupport.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    148148                $this->assertEqualSets( array( 'post_tag' ), $taxonomies );
    149149                $this->assertEqualSets( array(), $taxonomies_after );
    150150        }
     151
     152        /**
     153         * @ticket 37667
     154         */
     155        public function test_add_support_basic() {
     156                $post_type = rand_str( 20 );
     157                $post_type_object = register_post_type( $post_type );
     158
     159                $feature = 'custom_feature_name';
     160
     161                $post_type_object->add_support( $feature );
     162                $this->assertTrue( post_type_supports( $post_type, $feature ) );
     163        }
     164
     165        /**
     166         * @ticket 37667
     167         */
     168        public function test_add_support_with_subtype() {
     169                $post_type = rand_str( 20 );
     170                $post_type_object = register_post_type( $post_type );
     171
     172                $subtype = rand_str();
     173                $feature = 'custom_feature_name';
     174
     175                $post_type_object->add_support( $feature, true, $subtype );
     176                $this->assertTrue( post_type_supports( $post_type . ':' . $subtype, $feature ) );
     177        }
     178
     179        /**
     180         * @ticket 37667
     181         */
     182        public function test_remove_support_basic() {
     183                $post_type = rand_str( 20 );
     184                $post_type_object = register_post_type( $post_type );
     185
     186                $feature = 'editor';
     187
     188                $post_type_object->remove_support( $feature );
     189                $this->assertFalse( post_type_supports( $post_type, $feature ) );
     190        }
     191
     192        /**
     193         * @ticket 37667
     194         */
     195        public function test_remove_support_with_subtype() {
     196                $post_type = rand_str( 20 );
     197                $post_type_object = register_post_type( $post_type );
     198
     199                $subtype = rand_str();
     200                $feature = 'custom_feature_name';
     201
     202                add_post_type_support( $post_type . ':' . $subtype, $feature );
     203                $post_type_object->remove_support( $feature, $subtype );
     204                $this->assertFalse( post_type_supports( $post_type . ':' . $subtype, $feature ) );
     205        }
     206
     207        /**
     208         * @ticket 37667
     209         */
     210        public function test_get_all_supports_basic() {
     211                $post_type = rand_str( 20 );
     212                $post_type_object = register_post_type( $post_type );
     213
     214                $feature = 'custom_feature_name';
     215
     216                add_post_type_support( $post_type, $feature );
     217                $this->assertEqualSets( array(
     218                        'title' => true,
     219                        'editor' => true,
     220                        $feature => true,
     221                ), $post_type_object->get_all_supports() );
     222        }
     223
     224        /**
     225         * @ticket 37667
     226         */
     227        public function test_get_all_supports_with_subtype() {
     228                $post_type = rand_str( 20 );
     229                $post_type_object = register_post_type( $post_type );
     230
     231                $subtype = rand_str();
     232                $features = array( 'custom_feature_name', 'another_feature_name' );
     233
     234                add_post_type_support( $post_type . ':' . $subtype, $features );
     235                $this->assertEqualSets( array_fill_keys( $features, true ), $post_type_object->get_all_supports( $subtype ) );
     236        }
     237
     238        /**
     239         * @ticket 37667
     240         */
     241        public function test_supports_basic() {
     242                $post_type = rand_str( 20 );
     243                $post_type_object = register_post_type( $post_type );
     244
     245                $feature = 'custom_feature_name';
     246
     247                add_post_type_support( $post_type, $feature );
     248                $this->assertTrue( $post_type_object->supports( $feature ) );
     249        }
     250
     251        /**
     252         * @ticket 37667
     253         */
     254        public function test_supports_with_subtype() {
     255                $post_type = rand_str( 20 );
     256                $post_type_object = register_post_type( $post_type );
     257
     258                $subtype = rand_str();
     259                $feature = 'custom_feature_name';
     260
     261                add_post_type_support( $post_type . ':' . $subtype, $feature );
     262                $this->assertTrue( $post_type_object->supports( $feature, $subtype ) );
     263        }
     264
     265        /**
     266         * @ticket 37667
     267         */
     268        public function test_get_by_support() {
     269                $post_type = rand_str( 20 );
     270                $post_type_object = register_post_type( $post_type );
     271
     272                $subtype1 = rand_str();
     273                $subtype2 = rand_str();
     274                $feature = 'custom_feature_name';
     275
     276                add_post_type_support( $post_type, $feature );
     277                add_post_type_support( $post_type . ':' . $subtype2, $feature );
     278                $this->assertEqualSets( array( $post_type, $post_type . ':' . $subtype2 ), $post_type_object->get_by_support( $feature ) );
     279        }
     280
     281        /**
     282         * @ticket 37667
     283         */
     284        public function test_migrate_support_from_global() {
     285                $post_type = rand_str();
     286
     287                $feature = 'custom_feature_name';
     288
     289                WP_Post_Type::add_support_early( $post_type, $feature, true );
     290                $post_type_object = new WP_Post_Type( $post_type );
     291                $this->assertTrue( $post_type_object->supports( $feature ) );
     292        }
    151293}