Make WordPress Core

Changeset 55254


Ignore:
Timestamp:
02/07/2023 12:38:01 PM (22 months 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.