Make WordPress Core

Changeset 55254


Ignore:
Timestamp:
02/07/2023 12:38:01 PM (3 years ago)
Author:
audrasjb
Message:

Revisions: Add a way to filter the revisions considered for deletion.

This changeset introduces a new filter for wp_save_post_revision(). wp_save_post_revision_revisions_before_deletion passes the revisions to be considered for deletion, and the new revision's post ID.

This allows extenders to exclude specific revisions from being considered for deletion.

Props jhned, costdev, audrasjb, adamsilverstein, mukesh27.
Fixes #57320.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/revision.php

    r54870 r55254  
    201201        $revisions = wp_get_post_revisions( $post_id, array( 'order' => 'ASC' ) );
    202202
     203        /**
     204         * Filters the revisions to be considered for deletion.
     205         *
     206         * @since 6.2.0
     207         *
     208         * @param WP_Post[]|int[] $revisions Array of revision objects or IDs,
     209         *                                   or an empty array if none.
     210         * @param int             $post_id   The ID of the post to save as a revision.
     211         */
     212        $filtered_revisions = apply_filters(
     213                'wp_save_post_revision_revisions_before_deletion',
     214                $revisions,
     215                $post_id
     216        );
     217
     218        if ( is_array( $filtered_revisions ) ) {
     219                $revisions = $filtered_revisions;
     220        } else {
     221                _doing_it_wrong(
     222                        __FUNCTION__,
     223                        sprintf(
     224                                /* translators: %s: The filter name. */
     225                                __( 'The "%s" filter should return an array.' ),
     226                                'wp_save_post_revision_revisions_before_deletion'
     227                        ),
     228                        '6.2.0'
     229                );
     230        }
     231
    203232        $delete = count( $revisions ) - $revisions_to_keep;
    204233
  • trunk/tests/phpunit/tests/post/revisions.php

    r53853 r55254  
    867867                add_post_type_support( 'post', 'revisions' );
    868868        }
     869
     870        /**
     871         * Tests that wp_save_post_revision() respects the 'wp_save_post_revision_revisions_before_deletion' filter
     872         * when deleting revisions.
     873         *
     874         * This test should protect the original revision, send the rest to be checked against wp_revisions_to_keep(),
     875         * and result in two revisions: The latest revision, and the original.
     876         *
     877         * @ticket 57320
     878         *
     879         * @covers ::wp_save_post_revision
     880         */
     881        public function test_wp_save_post_revision_should_respect_revisions_before_deletion_filter() {
     882                $post_id = self::factory()->post->create( array( 'post_title' => 'Test 57320' ) );
     883
     884                add_filter(
     885                        'wp_revisions_to_keep',
     886                        static function() {
     887                                return 1;
     888                        }
     889                );
     890
     891                add_filter(
     892                        'wp_save_post_revision_revisions_before_deletion',
     893                        static function ( $revisions ) {
     894                                // Ignore the first revision and return the rest for deletion.
     895                                return array_slice( $revisions, 1 );
     896                        }
     897                );
     898
     899                for ( $update = 1; $update < 4; ++$update ) {
     900                        wp_update_post(
     901                                array(
     902                                        'ID'         => $post_id,
     903                                        'post_title' => 'Test 57320 Update ' . $update,
     904                                )
     905                        );
     906                }
     907
     908                $actual = wp_get_post_revisions( $post_id );
     909
     910                $this->assertCount(
     911                        2,
     912                        $actual,
     913                        'There should be two revisions.'
     914                );
     915
     916                $first  = reset( $actual );
     917                $second = next( $actual );
     918
     919                $this->assertSame(
     920                        'Test 57320 Update 3',
     921                        $first->post_title,
     922                        'The title of the first revision was incorrect.'
     923                );
     924
     925                $this->assertSame(
     926                        'Test 57320 Update 1',
     927                        $second->post_title,
     928                        'The title of the second revision was incorrect.'
     929                );
     930        }
     931
     932        /**
     933         * Tests that wp_save_post_revision() ignores an invalid return value
     934         * from the 'wp_save_post_revision_revisions_before_deletion' filter
     935         * and throws _doing_it_wrong().
     936         *
     937         * @ticket 57320
     938         *
     939         * @covers ::wp_save_post_revision
     940         *
     941         * @expectedIncorrectUsage wp_save_post_revision
     942         */
     943        public function test_wp_save_post_revision_should_ignore_invalid_revisions_before_deletion_filter() {
     944                $post_id = self::factory()->post->create( array( 'post_title' => 'Test 57320' ) );
     945
     946                add_filter(
     947                        'wp_revisions_to_keep',
     948                        static function() {
     949                                return 1;
     950                        }
     951                );
     952
     953                add_filter( 'wp_save_post_revision_revisions_before_deletion', '__return_null' );
     954
     955                for ( $update = 1; $update < 4; ++$update ) {
     956                        wp_update_post(
     957                                array(
     958                                        'ID'         => $post_id,
     959                                        'post_title' => 'Test 57320 Update ' . $update,
     960                                )
     961                        );
     962                }
     963
     964                $actual = wp_get_post_revisions( $post_id );
     965
     966                $this->assertCount(
     967                        1,
     968                        $actual,
     969                        'There should only be one revision.'
     970                );
     971
     972                $first = reset( $actual );
     973
     974                $this->assertSame(
     975                        'Test 57320 Update 3',
     976                        $first->post_title,
     977                        'The title of the first revision was incorrect.'
     978                );
     979        }
    869980}
Note: See TracChangeset for help on using the changeset viewer.