WordPress.org

Make WordPress Core

Ticket #32378: 32378-4.patch

File 32378-4.patch, 5.6 KB (added by mattday, 9 months ago)
  • wp-admin/includes/admin-filters.php

    a b  
    3131add_filter( 'async_upload_file',  'get_media_item', 10, 2 );
    3232
    3333add_filter( 'attachment_fields_to_save', 'image_attachment_fields_to_save', 10, 2 );
     34add_filter( 'wp_read_image_metadata', 'image_metadata_substitute_defaults', 10, 3 );
    3435
    3536add_filter( 'media_upload_gallery', 'media_upload_gallery' );
    3637add_filter( 'media_upload_library', 'media_upload_library' );
  • wp-admin/includes/image.php

    a b  
    516516}
    517517
    518518/**
     519 * Cleans up unwanted default metadata from images
     520 *
     521 * Some cameras store unwanted values in the EXIF data for
     522 * their photos. For example, some older Olympus cameras
     523 * store "OLYMPUS DIGITAL CAMERA" as the image caption.
     524 *
     525 * These values should probably never persist with the images
     526 * because they don't reflect the meaning of the same fields
     527 * from inside of WordPress.
     528 *
     529 * @since 4.9.8
     530 * @uses image_metadata_apply_substitution_rules
     531 *
     532 * @param array $meta image meta data
     533 * @param string $file path to image file
     534 * @param int $sourceImageType type of image
     535 * @return array $meta possibly transformed image meta
     536 */
     537function image_metadata_substitute_defaults( $meta, $file, $sourceImageType ) {
     538        /**
     539         * list of predicate/replacement pairs
     540         *
     541         * each predicate specifies a field name in the image meta
     542         * and a RegExp pattern to apply to the given field in order
     543         * to determine if the value should be replaced
     544         *
     545         * each replacement specifies the kind of replacement to
     546         * perform, the target field receiving the replacement value,
     547         * and the information needed to actually provide that value
     548         *
     549         * replacement types:
     550         *   EXIF   - use the value from a given EXIF field in the image
     551         *   string - use the given string value
     552         *   filename - use the name of the file, ignore value
     553         */
     554        $rules = array(
     555                'Olympus_Default_Title' => array(
     556                        array( 'field' => 'title', 'pattern' => '/^OLYMPUS DIGITAL CAMERA$/' ),
     557                        array( 'type' => 'filename', 'field' => 'title', 'value' => '' ),
     558                ),
     559                'Olympus_Default_Caption' => array(
     560                        array( 'field' => 'caption', 'pattern' => '/^OLYMPUS DIGITAL CAMERA$/' ),
     561                        array( 'type' => 'string', 'field' => 'caption', 'value' => '' ),
     562                )
     563        );
     564
     565        $image_types = apply_filters(
     566                'wp_read_image_metadata_types',
     567                array(
     568                        IMAGETYPE_JPEG,
     569                        IMAGETYPE_TIFF_II,
     570                        IMAGETYPE_TIFF_MM,
     571                )
     572        );
     573
     574        return image_metadata_apply_substitution_rules(
     575                $meta,
     576                $file,
     577                $sourceImageType,
     578                $rules,
     579                'exif_read_data',
     580                $image_types
     581        );
     582}
     583
     584/**
     585 * Applies transformations to image meta to remove unwanted defaults
     586 *
     587 * The rules in this function describe which values are
     588 * unwanted and how they should be replaced.
     589 *
     590 * @since 4.9.8
     591 * @used-by image_metadata_substitute_defaults
     592 * @internal
     593 *
     594 * @param array $meta image meta data
     595 * @param string $file path to image file
     596 * @param int $sourceImageType type of image
     597 * @param array $rules predicate/replacement pairs of metadata to replace
     598 * @param callable $exif_reader 'exif_read_data' or custom function for mock data while testing (file path -> EXIF array)
     599 * @param int[] $image_types list of valid image types on which to operate
     600 * @return array $meta possibly transformed image meta
     601 */
     602function image_metadata_apply_substitution_rules( $meta, $file, $sourceImageType, $rules, $exif_reader, $image_types ) {
     603
     604        /** @var string[] $substitutions list of rules which apply to the current image */
     605        $substitutions = array();
     606
     607        /** @var bool $need_exif_data if any of the applicable rules depend on image EXIF data */
     608        $need_exif_data = false;
     609
     610        // find which (if any) rules apply to the image
     611        foreach( $rules as $rule_name => $rule ) {
     612                list( $predicate, $replacement ) = $rule;
     613
     614                // only apply rule if meta values match given predicate
     615                if ( 1 !== preg_match( $predicate['pattern'], $meta[ $predicate['field'] ] ) ) {
     616                        continue;
     617                }
     618
     619                $substitutions[] = $rule_name;
     620                $need_exif_data = $need_exif_data || ( $replacement['type'] === 'EXIF' );
     621        }
     622
     623        // abort early if no substitutions are needed
     624        if ( 0 === count( $substitutions ) ) {
     625                return $meta;
     626        }
     627
     628        /** @var bool $can_get_exif_data if we _need_ and _can_ read the image EXIF data */
     629        $can_get_exif_data = (
     630                $need_exif_data &&
     631                is_callable( 'exif_read_data' ) &&
     632                in_array( $sourceImageType, $image_types )
     633        );
     634
     635        /** @var array|bool $raw_exif_data we might get `false` if no data is available */
     636        $raw_exif_data = $can_get_exif_data
     637                ? @call_user_func( $exif_reader, $file )
     638                : array();
     639
     640        /** @var array $exif_data normalized exif results where no data is an empty array */
     641        $exif_data = is_array( $raw_exif_data )
     642                ? $raw_exif_data
     643                : array();
     644
     645        /** @var array $updates holds the new meta field name / value pairs for replacement */
     646        $updates = array();
     647
     648        // build the list of replacements
     649        foreach( $substitutions as $rule_name ) {
     650                list( /* predicate */, $replacement ) = $rules[ $rule_name ];
     651
     652                if ( 'EXIF' === $replacement['type'] && ! empty( $exif_data[ $replacement['value'] ] ) ) {
     653                        $updates[ $replacement['field'] ] = trim( $exif_data[ $replacement['value'] ] );
     654                        continue;
     655                }
     656
     657                if ( 'string' === $replacement['type'] ) {
     658                        $updates[ $replacement['field'] ] = $replacement['value'];
     659                        continue;
     660                }
     661
     662                if ( 'filename' === $replacement['type'] ) {
     663                        $updates[ $replacement['field'] ] = pathinfo($file, PATHINFO_FILENAME);
     664                        continue;
     665                }
     666
     667        }
     668
     669        // return the transformed metadata
     670        return array_merge( $meta, $updates );
     671}
     672
     673/**
    519674 * Validate that file is an image.
    520675 *
    521676 * @since 2.5.0