mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
Post Types: Introduce unregister_post_type().
This new function can be used to completely unregister non built-in post types. Fixes #14761. git-svn-id: https://develop.svn.wordpress.org/trunk@36316 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
8e8cdb2ef4
commit
a111eafd41
@ -16,6 +16,8 @@
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $post_type_meta_caps Used to get post type meta capabilities.
|
||||
*
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id User ID.
|
||||
* @param int $object_id Optional. ID of the specific object to check against if `$cap` is a "meta" cap.
|
||||
@ -377,7 +379,7 @@ function map_meta_cap( $cap, $user_id ) {
|
||||
break;
|
||||
default:
|
||||
// Handle meta capabilities for custom post types.
|
||||
$post_type_meta_caps = _post_type_meta_capabilities();
|
||||
global $post_type_meta_caps;
|
||||
if ( isset( $post_type_meta_caps[ $cap ] ) ) {
|
||||
$args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
|
||||
return call_user_func_array( 'map_meta_cap', $args );
|
||||
|
||||
@ -1186,6 +1186,88 @@ function register_post_type( $post_type, $args = array() ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a post type.
|
||||
*
|
||||
* Can not be used to unregister built-in post types.
|
||||
*
|
||||
* @since 4.5.0
|
||||
*
|
||||
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
|
||||
* @global WP $wp Current WordPress environment instance.
|
||||
* @global array $_wp_post_type_features Used to remove post type features.
|
||||
* @global array $post_type_meta_caps Used to remove meta capabilities.
|
||||
* @global array $wp_post_types List of post types.
|
||||
*
|
||||
* @param string $post_type Post type key.
|
||||
* @return bool|WP_Error True on success, WP_Error on failure.
|
||||
*/
|
||||
function unregister_post_type( $post_type ) {
|
||||
if ( ! post_type_exists( $post_type ) ) {
|
||||
return new WP_Error( 'invalid_post_type', __( 'Invalid post type' ) );
|
||||
}
|
||||
|
||||
$post_type_args = get_post_type_object( $post_type );
|
||||
|
||||
// Do not allow unregistering internal post types.
|
||||
if ( $post_type_args->_builtin ) {
|
||||
return new WP_Error( 'invalid_post_type', __( 'Unregistering a built-in post type is not allowed' ) );
|
||||
}
|
||||
|
||||
global $wp, $wp_rewrite, $_wp_post_type_features, $post_type_meta_caps, $wp_post_types;
|
||||
|
||||
// Remove query var.
|
||||
if ( false !== $post_type_args->query_var ) {
|
||||
$wp->remove_query_var( $post_type_args->query_var );
|
||||
}
|
||||
|
||||
// Remove any rewrite rules, permastructs, and rules.
|
||||
if ( false !== $post_type_args->rewrite ) {
|
||||
remove_rewrite_tag( "%$post_type%" );
|
||||
remove_permastruct( $post_type );
|
||||
foreach ( $wp_rewrite->extra_rules_top as $regex => $query ) {
|
||||
if ( false !== strpos( $query, "index.php?post_type=$post_type" ) ) {
|
||||
unset( $wp_rewrite->extra_rules_top[ $regex ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove registered custom meta capabilities.
|
||||
foreach ( $post_type_args->cap as $cap ) {
|
||||
unset( $post_type_meta_caps[ $cap ] );
|
||||
}
|
||||
|
||||
// Remove all post type support.
|
||||
unset( $_wp_post_type_features[ $post_type ] );
|
||||
|
||||
// Unregister the post type meta box if a custom callback was specified.
|
||||
if ( $post_type_args->register_meta_box_cb ) {
|
||||
remove_action( 'add_meta_boxes_' . $post_type, $post_type_args->register_meta_box_cb );
|
||||
}
|
||||
|
||||
// Remove the post type from all taxonomies.
|
||||
foreach ( get_object_taxonomies( $post_type ) as $taxonomy ) {
|
||||
unregister_taxonomy_for_object_type( $taxonomy, $post_type );
|
||||
}
|
||||
|
||||
// Remove the future post hook action.
|
||||
remove_action( 'future_' . $post_type, '_future_post_hook', 5 );
|
||||
|
||||
// Remove the post type.
|
||||
unset( $wp_post_types[ $post_type ] );
|
||||
|
||||
/**
|
||||
* Fires after a post type was unregistered.
|
||||
*
|
||||
* @since 4.5.0
|
||||
*
|
||||
* @param string $post_type Post type key.
|
||||
*/
|
||||
do_action( 'unregistered_post_type', $post_type );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an object with all post type capabilities out of a post type object
|
||||
*
|
||||
@ -1293,17 +1375,17 @@ function get_post_type_capabilities( $args ) {
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*
|
||||
* @staticvar array $meta_caps
|
||||
* @global array $post_type_meta_caps Used to store meta capabilities.
|
||||
*
|
||||
* @param array|void $capabilities Post type meta capabilities.
|
||||
* @param array $capabilities Post type meta capabilities.
|
||||
*/
|
||||
function _post_type_meta_capabilities( $capabilities = null ) {
|
||||
static $meta_caps = array();
|
||||
if ( null === $capabilities )
|
||||
return $meta_caps;
|
||||
global $post_type_meta_caps;
|
||||
|
||||
foreach ( $capabilities as $core => $custom ) {
|
||||
if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ) ) )
|
||||
$meta_caps[ $custom ] = $core;
|
||||
if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ) ) ) {
|
||||
$post_type_meta_caps[ $custom ] = $core;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -335,14 +335,7 @@ if ( !function_exists( 'str_getcsv' ) ) {
|
||||
* Removes the post type and its taxonomy associations.
|
||||
*/
|
||||
function _unregister_post_type( $cpt_name ) {
|
||||
unset( $GLOBALS['wp_post_types'][ $cpt_name ] );
|
||||
unset( $GLOBALS['_wp_post_type_features'][ $cpt_name ] );
|
||||
|
||||
foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy ) {
|
||||
if ( false !== $key = array_search( $cpt_name, $taxonomy->object_type ) ) {
|
||||
unset( $taxonomy->object_type[$key] );
|
||||
}
|
||||
}
|
||||
unregister_post_type( $cpt_name );
|
||||
}
|
||||
|
||||
function _unregister_taxonomy( $taxonomy_name ) {
|
||||
|
||||
@ -159,4 +159,224 @@ class Tests_Post_Types extends WP_UnitTestCase {
|
||||
|
||||
_unregister_post_type( 'foo' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type() {
|
||||
register_post_type( 'foo' );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_unknown_post_type() {
|
||||
$this->assertWPError( unregister_post_type( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_twice() {
|
||||
register_post_type( 'foo' );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertWPError( unregister_post_type( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_disallow_builtin_post_type() {
|
||||
$this->assertWPError( unregister_post_type( 'post' ) );
|
||||
$this->assertWPError( unregister_post_type( 'page' ) );
|
||||
$this->assertWPError( unregister_post_type( 'attachment' ) );
|
||||
$this->assertWPError( unregister_post_type( 'revision' ) );
|
||||
$this->assertWPError( unregister_post_type( 'nav_menu_item' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_query_vars() {
|
||||
global $wp;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'query_var' => 'bar',
|
||||
) );
|
||||
|
||||
$this->assertInternalType( 'int', array_search( 'bar', $wp->public_query_vars ) );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertFalse( array_search( 'bar', $wp->public_query_vars ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_rewrite_tags() {
|
||||
$this->set_permalink_structure( '/%postname%' );
|
||||
|
||||
global $wp_rewrite;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'query_var' => 'bar',
|
||||
) );
|
||||
|
||||
$count_before = count( $wp_rewrite->rewritereplace );
|
||||
|
||||
$this->assertContains( '%foo%', $wp_rewrite->rewritecode );
|
||||
$this->assertContains( 'bar=', $wp_rewrite->queryreplace );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertNotContains( '%foo%', $wp_rewrite->rewritecode );
|
||||
$this->assertNotContains( 'bar=', $wp_rewrite->queryreplace );
|
||||
$this->assertSame( -- $count_before, count( $wp_rewrite->rewritereplace ) ); // Array was reduced by one value.
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_rewrite_rules() {
|
||||
$this->set_permalink_structure( '/%postname%' );
|
||||
|
||||
global $wp_rewrite;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'has_archive' => true,
|
||||
) );
|
||||
|
||||
$this->assertContains( 'index.php?post_type=foo', $wp_rewrite->extra_rules_top );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertNotContains( 'index.php?post_type=foo', $wp_rewrite->extra_rules_top );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_custom_meta_capabilities() {
|
||||
global $post_type_meta_caps;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'capability_type' => 'bar',
|
||||
'map_meta_cap' => true,
|
||||
) );
|
||||
|
||||
$this->assertSame( 'read_post', $post_type_meta_caps['read_bar'] );
|
||||
$this->assertSame( 'delete_post', $post_type_meta_caps['delete_bar'] );
|
||||
$this->assertSame( 'edit_post', $post_type_meta_caps['edit_bar'] );
|
||||
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
|
||||
$this->assertFalse( isset( $post_type_meta_caps['read_bar'] ) );
|
||||
$this->assertFalse( isset( $post_type_meta_caps['delete_bar'] ) );
|
||||
$this->assertFalse( isset( $post_type_meta_caps['edit_bar'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_post_type_supports() {
|
||||
global $_wp_post_type_features;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'supports' => array( 'editor', 'author', 'title' ),
|
||||
) );
|
||||
|
||||
$this->assertEqualSetsWithIndex(
|
||||
array(
|
||||
'editor' => true,
|
||||
'author' => true,
|
||||
'title' => true,
|
||||
),
|
||||
$_wp_post_type_features['foo']
|
||||
);
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertFalse( isset( $_wp_post_type_features['foo'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_post_type_from_taxonomies() {
|
||||
global $wp_taxonomies;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'taxonomies' => array( 'category', 'post_tag' ),
|
||||
) );
|
||||
|
||||
$this->assertInternalType( 'int', array_search( 'foo', $wp_taxonomies['category']->object_type, true ) );
|
||||
$this->assertInternalType( 'int', array_search( 'foo', $wp_taxonomies['post_tag']->object_type, true ) );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertFalse( array_search( 'foo', $wp_taxonomies['category']->object_type, true ) );
|
||||
$this->assertFalse( array_search( 'foo', $wp_taxonomies['post_tag']->object_type, true ) );
|
||||
$this->assertEmpty( get_object_taxonomies( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_the_future_post_hooks() {
|
||||
global $wp_filter;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
) );
|
||||
|
||||
$this->assertSame( 1, count( $wp_filter['future_foo'] ) );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertSame( array(), $wp_filter['future_foo'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_meta_box_callback() {
|
||||
global $wp_filter;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
'register_meta_box_cb' => '__return_empty_string',
|
||||
) );
|
||||
|
||||
$this->assertSame( 1, count( $wp_filter['add_meta_boxes_foo'] ) );
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
$this->assertSame( array(), $wp_filter['add_meta_boxes_foo'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_unregister_post_type_removes_post_type_from_global() {
|
||||
global $wp_post_types;
|
||||
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
) );
|
||||
|
||||
$this->assertInternalType( 'object', $wp_post_types['foo'] );
|
||||
$this->assertInternalType( 'object', get_post_type_object( 'foo' ) );
|
||||
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
|
||||
$this->assertFalse( isset( $wp_post_types['foo'] ) );
|
||||
$this->assertNull( get_post_type_object( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 14761
|
||||
*/
|
||||
public function test_post_type_does_not_exist_after_unregister_post_type() {
|
||||
register_post_type( 'foo', array(
|
||||
'public' => true,
|
||||
) );
|
||||
|
||||
$this->assertTrue( unregister_post_type( 'foo' ) );
|
||||
|
||||
$this->assertFalse( post_type_exists( 'foo' ) );
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user