Make WordPress Core

Changeset 59118


Ignore:
Timestamp:
09/30/2024 03:17:31 AM (12 days ago)
Author:
peterwilsoncc
Message:

Media: Add short-circuit filter to attachment_url_to_postid().

Introduces the filter pre_attachment_url_to_postid to allow developers to short-circuit the function attachment_url_to_postid().

The return values are expected to be an attachment ID, zero (0) to indicate no attachment was found or null to indicate the function should proceed as usual.

The function performs an expensive database query so developers making use of the function frequently may wish to use a custom table with appropriate indexes to reduce the load on their database server.

Props antpb, apermo, audrasjb, joedolson.
Fixes #61383.

Location:
trunk
Files:
2 edited

Legend:

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

    r59008 r59118  
    53845384    global $wpdb;
    53855385
     5386    /**
     5387     * Filters the attachment ID to allow short-circuit the function.
     5388     *
     5389     * Allows plugins to short-circuit attachment ID lookups. Plugins making
     5390     * use of this function should return:
     5391     *
     5392     * - 0 (integer) to indicate the attachment is not found,
     5393     * - attachment ID (integer) to indicate the attachment ID found,
     5394     * - null to indicate WordPress should proceed with the lookup.
     5395     *
     5396     * Warning: The post ID may be null or zero, both of which cast to a
     5397     * boolean false. For information about casting to booleans see the
     5398     * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}.
     5399     * Use the === operator for testing the post ID when developing filters using
     5400     * this hook.
     5401     *
     5402     * @param int|null $post_id The result of the post ID lookup. Null to indicate
     5403     *                          no lookup has been attempted. Default null.
     5404     * @param string   $url     The URL being looked up.
     5405     */
     5406    $post_id = apply_filters( 'pre_attachment_url_to_postid', null, $url );
     5407    if ( null !== $post_id ) {
     5408        return (int) $post_id;
     5409    }
     5410
    53865411    $dir  = wp_get_upload_dir();
    53875412    $path = $url;
  • trunk/tests/phpunit/tests/media.php

    r59008 r59118  
    12721272        $this->assertSame( $attachment_id, attachment_url_to_postid( $image_url ) );
    12731273        remove_filter( 'upload_dir', array( $this, 'upload_dir' ) );
     1274    }
     1275
     1276    /**
     1277     * Test short-circuiting the attachment_url_to_postid filter.
     1278     *
     1279     * @ticket 61383
     1280     */
     1281    public function test_attachment_url_to_postid_short_circuit_filter_prevents_db_queries() {
     1282        $image_path    = '2014/11/' . self::IMG_NAME;
     1283        $attachment_id = self::factory()->attachment->create_object(
     1284            $image_path,
     1285            0,
     1286            array(
     1287                'post_mime_type' => 'image/jpeg',
     1288                'post_type'      => 'attachment',
     1289            )
     1290        );
     1291        $image_url     = wp_get_attachment_url( $attachment_id );
     1292
     1293        add_filter(
     1294            'pre_attachment_url_to_postid',
     1295            function () use ( $attachment_id ) {
     1296                return $attachment_id;
     1297            }
     1298        );
     1299
     1300        $queries_before = get_num_queries();
     1301        $this->assertSame( $attachment_id, attachment_url_to_postid( $image_url ), 'The filter should short-circuit the function' );
     1302        $queries_after = get_num_queries();
     1303        $this->assertSame( 0, $queries_after - $queries_before, 'No database queries should be made by a short-circuited function' );
     1304    }
     1305
     1306    /**
     1307     * Test short-circuiting the attachment_url_to_postid filter with a not found result.
     1308     *
     1309     * @ticket 61383
     1310     */
     1311    public function test_attachment_url_to_postid_short_circuit_filter_when_attachment_does_not_exist() {
     1312        add_filter( 'pre_attachment_url_to_postid', '__return_zero' );
     1313
     1314        $queries_before = get_num_queries();
     1315        $this->assertSame( 0, attachment_url_to_postid( 'http://example.org/wp-content/uploads/2014/11/image.jpg' ), 'The filter should short-circuit the function' );
     1316        $queries_after = get_num_queries();
     1317        $this->assertSame( 0, $queries_after - $queries_before, 'No database queries should be made by a short-circuited function' );
     1318    }
     1319
     1320    /**
     1321     * Test short-circuiting the attachment_url_to_postid filter with a proceed result.
     1322     *
     1323     * @ticket 61383
     1324     */
     1325    public function test_attachment_url_to_postid_short_circuit_filter_should_proceed_if_filter_returns_null() {
     1326        $image_path    = '2014/11/' . self::IMG_NAME;
     1327        $attachment_id = self::factory()->attachment->create_object(
     1328            $image_path,
     1329            0,
     1330            array(
     1331                'post_mime_type' => 'image/jpeg',
     1332                'post_type'      => 'attachment',
     1333            )
     1334        );
     1335        $image_url     = wp_get_attachment_url( $attachment_id );
     1336
     1337        add_filter( 'pre_attachment_url_to_postid', '__return_null' );
     1338
     1339        $queries_before = get_num_queries();
     1340        $this->assertSame( $attachment_id, attachment_url_to_postid( $image_url ), 'The filter should return the attachment ID' );
     1341        $queries_after = get_num_queries();
     1342        $this->assertGreaterThan( 0, $queries_after - $queries_before, 'Database queries are expected when the filter returns null' );
    12741343    }
    12751344
Note: See TracChangeset for help on using the changeset viewer.