Make WordPress Core

Changeset 41732


Ignore:
Timestamp:
10/04/2017 02:58:07 PM (7 years ago)
Author:
joemcgill
Message:

Customizer: Minimize duplicate header crops in the media library.

This adds Custom_Image_Header::get_previous_crop(), which finds any
previously cropped headers created from the same base image and replaces
that attachment rather than creating a new attachment.

After updating a crop, the replaced images is also removed from the list
of previous header images in the Customizer.

See #21819.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/custom-header.php

    r41161 r41732  
    11651165            'post_mime_type' => $image_type,
    11661166            'guid' => $url,
    1167             'context' => 'custom-header'
     1167            'context' => 'custom-header',
     1168            'post_parent' => $parent_attachment_id,
    11681169        );
    11691170
     
    11811182     */
    11821183    final public function insert_attachment( $object, $cropped ) {
     1184        $parent_id = isset( $object['post_parent'] ) ? $object['post_parent'] : null;
     1185        unset( $object['post_parent'] );
     1186
    11831187        $attachment_id = wp_insert_attachment( $object, $cropped );
    11841188        $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped );
     1189
    11851190        /**
    11861191         * Filters the header image attachment metadata.
     
    11941199        $metadata = apply_filters( 'wp_header_image_attachment_metadata', $metadata );
    11951200        wp_update_attachment_metadata( $attachment_id, $metadata );
     1201
     1202        if ( $parent_id ) {
     1203            $meta = add_post_meta( $attachment_id, '_wp_attachment_parent', $parent_id, true );
     1204        }
     1205
    11961206        return $attachment_id;
    11971207    }
     
    12421252        $object = $this->create_attachment_object( $cropped, $attachment_id );
    12431253
    1244         unset( $object['ID'] );
     1254        $previous = $this->get_previous_crop( $object );
     1255
     1256        if ( $previous ) {
     1257            $object['ID'] = $previous;
     1258        } else {
     1259            unset( $object['ID'] );
     1260        }
    12451261
    12461262        $new_attachment_id = $this->insert_attachment( $object, $cropped );
     
    13971413        return $header_images;
    13981414    }
     1415
     1416    /**
     1417     * Get the ID of a previous crop from the same base image.
     1418     *
     1419     * @since 4.9.0
     1420     *
     1421     * @param  array $object A crop attachment object.
     1422     * @return int|false An attachment ID if one exists. False if none.
     1423     */
     1424    public function get_previous_crop( $object ) {
     1425        $header_images = $this->get_uploaded_header_images();
     1426
     1427        // Bail early if there are no header images.
     1428        if ( empty( $header_images ) ) {
     1429            return false;
     1430        }
     1431
     1432        $previous = false;
     1433
     1434        foreach ( $header_images as $image ) {
     1435            if ( $image['attachment_parent'] === $object['post_parent'] ) {
     1436                $previous = $image['attachment_id'];
     1437                break;
     1438            }
     1439        }
     1440
     1441        return $previous;
     1442    }
    13991443}
  • trunk/src/wp-includes/js/customize-models.js

    r41351 r41732  
    165165            this.on('control:setImage', this.setImage, this);
    166166            this.on('control:removeImage', this.removeImage, this);
     167            this.on('add', this.maybeRemoveOldCrop, this);
    167168            this.on('add', this.maybeAddRandomChoice, this);
    168169
     
    185186            if (this.size() > 0) {
    186187                this.addRandomChoice(current);
     188            }
     189        },
     190
     191        maybeRemoveOldCrop: function( model ) {
     192            var newID = model.get( 'header' ).attachment_id || false,
     193                oldCrop;
     194
     195            // Bail early if we don't have a new attachment ID.
     196            if ( ! newID ) {
     197                return;
     198            }
     199
     200            oldCrop = this.find( function( item ) {
     201                return ( item.cid !== model.cid && item.get( 'header' ).attachment_id === newID );
     202            } );
     203
     204            // If we found an old crop, remove it from the collection.
     205            if ( oldCrop ) {
     206                this.remove( oldCrop );
    187207            }
    188208        },
  • trunk/src/wp-includes/theme.php

    r41673 r41732  
    12151215        $header_images[$header_index]['thumbnail_url'] = $url;
    12161216        $header_images[$header_index]['alt_text'] = get_post_meta( $header->ID, '_wp_attachment_image_alt', true );
     1217        $header_images[$header_index]['attachment_parent'] = (int) get_post_meta( $header->ID, '_wp_attachment_parent', true );
    12171218
    12181219        if ( isset( $header_data['width'] ) )
  • trunk/tests/phpunit/tests/image/header.php

    r41017 r41732  
    138138    }
    139139
     140    /**
     141     * @ticket 21819
     142     */
     143    function test_check_get_previous_crop() {
     144        $id = wp_insert_attachment( array(
     145            'post_status' => 'publish',
     146            'post_title' => 'foo.png',
     147            'post_type' => 'post',
     148            'guid' => 'http://localhost/foo.png'
     149        ) );
     150
     151        // Create inital crop object.
     152        $cropped_1 = 'foo-cropped-1.png';
     153        $object = $this->custom_image_header->create_attachment_object( $cropped_1, $id );
     154
     155        // Ensure no previous crop exists.
     156        $previous = $this->custom_image_header->get_previous_crop( $object );
     157        $this->assertFalse( $previous );
     158
     159        // Create the inital crop attachment and set it as the header.
     160        $cropped_1_id = $this->custom_image_header->insert_attachment( $object, $cropped_1 );
     161        $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
     162        update_post_meta( $cropped_1_id, $key, time() );
     163        update_post_meta( $cropped_1_id, '_wp_attachment_is_custom_header', get_stylesheet() );
     164
     165        // Create second crop.
     166        $cropped_2 = 'foo-cropped-2.png';
     167        $object = $this->custom_image_header->create_attachment_object( $cropped_2, $id );
     168
     169        // Test that a previous crop is found.
     170        $previous = $this->custom_image_header->get_previous_crop( $object );
     171        $this->assertSame( $previous, $cropped_1_id );
     172    }
    140173}
Note: See TracChangeset for help on using the changeset viewer.