WordPress.org

Make WordPress Core

Ticket #40685: 40685.patch

File 40685.patch, 12.3 KB (added by gitlost, 5 years ago)

Demo patch, with unit tests.

  • src/wp-includes/class-wp-hook.php

     
    109109        private function resort_active_iterations( $new_priority = false, $priority_existed = false ) {
    110110                $new_priorities = array_keys( $this->callbacks );
    111111
    112                 // If there are no remaining hooks, clear out all running iterations.
    113                 if ( ! $new_priorities ) {
    114                         foreach ( $this->iterations as $index => $iteration ) {
    115                                 $this->iterations[ $index ] = $new_priorities;
    116                         }
    117                         return;
    118                 }
    119 
    120112                $min = min( $new_priorities );
    121113                foreach ( $this->iterations as $index => &$iteration ) {
    122114                        $current = current( $iteration );
     
    182174                $exists = isset( $this->callbacks[ $priority ][ $function_key ] );
    183175                if ( $exists ) {
    184176                        unset( $this->callbacks[ $priority ][ $function_key ] );
    185                         if ( ! $this->callbacks[ $priority ] ) {
    186                                 unset( $this->callbacks[ $priority ] );
    187                                 if ( $this->nesting_level > 0 ) {
    188                                         $this->resort_active_iterations();
    189                                 }
    190                         }
    191177                }
    192178                return $exists;
    193179        }
     
    254240
    255241                if ( false === $priority ) {
    256242                        $this->callbacks = array();
     243                        if ( $this->nesting_level > 0 ) {
     244                                foreach ( $this->iterations as $index => $iteration ) {
     245                                        $this->iterations[ $index ] = array();
     246                                }
     247                        }
    257248                } else if ( isset( $this->callbacks[ $priority ] ) ) {
    258                         unset( $this->callbacks[ $priority ] );
     249                        $this->callbacks[ $priority ] = array();
    259250                }
    260 
    261                 if ( $this->nesting_level > 0 ) {
    262                         $this->resort_active_iterations();
    263                 }
    264251        }
    265252
    266253        /**
  • tests/phpunit/tests/filters.php

     
    380380                global $wp_filter;
    381381                $this->current_priority = $wp_filter[ 'the_content' ]->current_priority();
    382382        }
     383
     384        /**
     385         * @ticket 40685
     386         */
     387        public function test_add_three_filters_and_middle_self_remove() {
     388                add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     389                add_filter( 'ticket_40685', array( $this, '_filter_middle_self_remove' ), 2, 1 );
     390                add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     391
     392                $value = apply_filters( 'ticket_40685', '' );
     393                $this->assertSame( '1r23', $value );
     394        }
     395
     396        public function _filter_first( $value ) {
     397                return $value . '1';
     398        }
     399
     400        public function _filter_middle( $value ) {
     401                return $value . '2';
     402        }
     403
     404        public function _filter_last( $value ) {
     405                return $value . '3';
     406        }
     407
     408        public function _filter_middle_self_remove( $value ) {
     409                remove_filter( 'ticket_40685', array( $this, __FUNCTION__ ), 2 );
     410                return $value . 'r2';
     411        }
    383412}
  • tests/phpunit/tests/hooks/add_filter.php

     
    277277        public function _action_remove_and_add4() {
    278278                $this->action_output .= '4';
    279279        }
     280
     281        /**
     282         * @ticket 40685
     283         */
     284        public function test_add_three_filters_and_middle_self_remove() {
     285                $this->hook = new Wp_Hook();
     286                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     287                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle_self_remove' ), 2, 1 );
     288                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     289
     290                $value = $this->hook->apply_filters( '', array() );
     291                $this->assertSame( '1r23', $value );
     292        }
     293
     294        /**
     295         * @ticket 40685
     296         */
     297        public function test_add_four_filters_and_middle_self_remove_and_middle2_self_remove() {
     298                $this->hook = new Wp_Hook();
     299                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     300                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle_self_remove' ), 2, 1 );
     301                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle2_self_remove' ), 2, 1 );
     302                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     303
     304                $value = $this->hook->apply_filters( '', array() );
     305                $this->assertSame( '1r2rr23', $value );
     306        }
     307
     308        /**
     309         * @ticket 40685
     310         */
     311        public function test_add_four_filters_and_middle_self_remove_and_middle_remove_before() {
     312                $this->hook = new Wp_Hook();
     313                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     314                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle_self_remove_and_middle_remove' ), 2, 1 );
     315                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2, 1 );
     316                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     317
     318                $value = $this->hook->apply_filters( '', array() );
     319                $this->assertSame( '1rb223', $value );
     320        }
     321
     322        /**
     323         * @ticket 40685
     324         */
     325        public function test_add_four_filters_and_middle_self_remove_and_middle_remove_after() {
     326                $this->hook = new Wp_Hook();
     327                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     328                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2, 1 );
     329                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle_self_remove_and_middle_remove' ), 2, 1 );
     330                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     331
     332                $value = $this->hook->apply_filters( '', array() );
     333                $this->assertSame( '12rb23', $value );
     334        }
     335
     336        public function _filter_first( $value ) {
     337                return $value . '1';
     338        }
     339
     340        public function _filter_middle( $value ) {
     341                return $value . '2';
     342        }
     343
     344        public function _filter_middle2( $value ) {
     345                return $value . 'm2';
     346        }
     347
     348        public function _filter_last( $value ) {
     349                return $value . '3';
     350        }
     351
     352        public function _filter_middle_self_remove( $value ) {
     353                $this->hook->remove_filter( 'ticket_40685', array( $this, __FUNCTION__ ), 2 );
     354                return $value . 'r2';
     355        }
     356
     357        public function _filter_middle2_self_remove( $value ) {
     358                $this->hook->remove_filter( 'ticket_40685', array( $this, __FUNCTION__ ), 2 );
     359                return $value . 'rr2';
     360        }
     361
     362        public function _filter_middle_self_remove_and_middle_remove( $value ) {
     363                $this->hook->remove_filter( 'ticket_40685', array( $this, __FUNCTION__ ), 2 );
     364                $this->hook->remove_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2 );
     365                return $value . 'rb2';
     366        }
    280367}
  • tests/phpunit/tests/hooks/remove_all_filters.php

     
    77 */
    88class Tests_WP_Hook_Remove_All_Filters extends WP_UnitTestCase {
    99
     10        public $hook;
     11
    1012        public function test_remove_all_filters() {
    1113                $callback = '__return_null';
    1214                $hook = new WP_Hook();
     
    3840                $this->assertTrue( $hook->has_filters() );
    3941                $this->assertEquals( $priority + 1, $hook->has_filter( $tag, $callback_two ) );
    4042        }
     43
     44        /**
     45         * @ticket 40685
     46         */
     47        public function test_remove_all_filters_with_priority_in_filter_before_other_middles() {
     48                $this->hook = new Wp_Hook();
     49                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     50                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_remove_all_priority2' ), 2, 1 );
     51                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2, 1 );
     52                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle2' ), 2, 1 );
     53                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     54
     55                $value = $this->hook->apply_filters( '', array() );
     56                $this->assertSame( '1rp22m23', $value ); // Note priority 2 hooks will still be run.
     57        }
     58
     59        /**
     60         * @ticket 40685
     61         */
     62        public function test_remove_all_filters_with_priority_in_filter_in_the_middle() {
     63                $this->hook = new Wp_Hook();
     64                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     65                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2, 1 );
     66                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_remove_all_priority2' ), 2, 1 );
     67                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle2' ), 2, 1 );
     68                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     69
     70                $value = $this->hook->apply_filters( '', array() );
     71                $this->assertSame( '12rp2m23', $value ); // Note priority 2 hooks will still be run.
     72        }
     73
     74        /**
     75         * @ticket 40685
     76         */
     77        public function test_remove_all_filters_with_priority_in_filter_after_other_middles() {
     78                $this->hook = new Wp_Hook();
     79                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_first' ), 1, 1 );
     80                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle' ), 2, 1 );
     81                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_middle2' ), 2, 1 );
     82                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_remove_all_priority2' ), 2, 1 );
     83                $this->hook->add_filter( 'ticket_40685', array( $this, '_filter_last' ), 3, 1 );
     84
     85                $value = $this->hook->apply_filters( '', array() );
     86                $this->assertSame( '12m2rp23', $value );
     87        }
     88
     89        public function _filter_first( $value ) {
     90                return $value . '1';
     91        }
     92
     93        public function _filter_middle( $value ) {
     94                return $value . '2';
     95        }
     96
     97        public function _filter_middle2( $value ) {
     98                return $value . 'm2';
     99        }
     100
     101        public function _filter_last( $value ) {
     102                return $value . '3';
     103        }
     104
     105        public function _filter_remove_all( $value ) {
     106                $this->hook->remove_all_filters();
     107                return $value . 'ra';
     108        }
     109
     110        public function _filter_remove_all_priority2( $value ) {
     111                $this->hook->remove_all_filters( 2 );
     112                return $value . 'rp2';
     113        }
    41114}
  • tests/phpunit/tests/hooks/remove_filter.php

     
    1717                $hook->add_filter( $tag, $callback, $priority, $accepted_args );
    1818                $hook->remove_filter( $tag, $callback, $priority );
    1919
    20                 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) );
     20                $this->assertEmpty( $hook->callbacks[ $priority ] );
    2121        }
    2222
    2323        public function test_remove_filter_with_object() {
     
    3131                $hook->add_filter( $tag, $callback, $priority, $accepted_args );
    3232                $hook->remove_filter( $tag, $callback, $priority );
    3333
    34                 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) );
     34                $this->assertEmpty( $hook->callbacks[ $priority ] );
    3535        }
    3636
    3737        public function test_remove_filter_with_static_method() {
     
    4444                $hook->add_filter( $tag, $callback, $priority, $accepted_args );
    4545                $hook->remove_filter( $tag, $callback, $priority );
    4646
    47                 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) );
     47                $this->assertEmpty( $hook->callbacks[ $priority ] );
    4848        }
    4949
    5050        public function test_remove_filters_with_another_at_same_priority() {
     
    7575                $hook->add_filter( $tag, $callback_two, $priority + 1, $accepted_args );
    7676
    7777                $hook->remove_filter( $tag, $callback_one, $priority );
    78                 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) );
     78                $this->assertEmpty( $hook->callbacks[ $priority ] );
    7979                $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] );
    8080        }
    8181}
  • tests/phpunit/tests/post/types.php

     
    425425
    426426                $this->assertSame( 1, count( $wp_filter['future_foo'] ) );
    427427                $this->assertTrue( unregister_post_type( 'foo' ) );
    428                 $this->assertArrayNotHasKey( 'future_foo', $wp_filter );
     428                $this->assertFalse( has_filter( 'future_foo' ) );
    429429        }
    430430
    431431        /**
     
    441441
    442442                $this->assertSame( 1, count( $wp_filter['add_meta_boxes_foo'] ) );
    443443                $this->assertTrue( unregister_post_type( 'foo' ) );
    444                 $this->assertArrayNotHasKey( 'add_meta_boxes_foo', $wp_filter );
     444                $this->assertFalse( has_filter( 'add_meta_boxes_foo' ) );
    445445        }
    446446
    447447        /**
  • tests/phpunit/tests/taxonomy.php

     
    697697
    698698                $this->assertSame( 1, count( $wp_filter['wp_ajax_add-foo'] ) );
    699699                $this->assertTrue( unregister_taxonomy( 'foo' ) );
    700                 $this->assertArrayNotHasKey( 'wp_ajax_add-foo', $wp_filter );
     700                $this->assertFalse( has_filter( 'wp_ajax_add-foo' ) );
    701701        }
    702702
    703703        /**