WordPress.org

Make WordPress Core

Ticket #49413: 49413.diff

File 49413.diff, 3.7 KB (added by dshanske, 7 weeks ago)

Proof of Concept

  • src/wp-admin/includes/image.php

    diff --git a/src/wp-admin/includes/image.php b/src/wp-admin/includes/image.php
    index f910809..3265189 100644
    a b function wp_exif_frac2dec( $str ) { 
    646646}
    647647
    648648/**
     649 * Convert the exif date format to a datetime object
     650 *
     651 * @since 5.5.0
     652 *
     653 * @param string $str
     654 * @param string $timezone A timezone or offset string. Default is the WordPress timezone
     655 * @return DateTimeImmutable| false Return false if not valid date
     656 */
     657function wp_exif_datetime( $str, $timezone = null ) {
     658        $timezone = ( $offset ) ? new DateTimeZone( $timezone ) : wp_timezone();
     659        $datetime = new DateTimeImmutable( $str, $timezone );
     660        return $datetime;
     661}
     662
     663
     664/**
    649665 * Convert the exif date format to a unix timestamp.
    650666 *
    651667 * @since 2.5.0
     668 * @since 5.5.0 Switched to using the wp_exif_datetime function to generate the timestamp for backcompat
    652669 *
    653670 * @param string $str
    654  * @return int
     671 * @return int|false If error return false
    655672 */
    656673function wp_exif_date2ts( $str ) {
    657         list( $date, $time ) = explode( ' ', trim( $str ) );
    658         list( $y, $m, $d )   = explode( ':', $date );
     674        $datetime = wp_exif_datetime( $str );
     675        if( $datetime ) {
     676                return $datetime->getTimestamp();
     677        }
     678        return false;
     679}
    659680
    660         return strtotime( "{$y}-{$m}-{$d} {$time}" );
     681/**
     682 * Combines the EXIF GPSTimeStamp and GPSDateStamp into a DateTime object
     683 *
     684 * @param string $datestamp
     685 * @param array $timestamp
     686 * @return DateTimeImmutable|false False if not valid data
     687 */
     688function wp_exif_gpsdatetime( $datestamp, $timestamp ) {
     689        if ( ! is_array( $timestamp ) ) {
     690                return false;
     691        }
     692        return new DateTimeImmutable(
     693                sprintf( '%s %02d:%02d:%02d', $datestamp, (int) $timestamp[0], (int) $timestamp[1], (int) $timestamp[2] ), new DateTimeZone( 'UTC' ) );
    661694}
    662695
    663696/**
    function wp_read_image_metadata( $file ) { 
    813846                if ( ! empty( $exif['Model'] ) ) {
    814847                        $meta['camera'] = trim( $exif['Model'] );
    815848                }
    816                 if ( empty( $meta['created_timestamp'] ) && ! empty( $exif['DateTimeDigitized'] ) ) {
    817                         $meta['created_timestamp'] = wp_exif_date2ts( $exif['DateTimeDigitized'] );
     849                if ( empty( $meta['created_timestamp'] ) ) {
     850                        $rawdate = null;
     851                        $timezone = null;
     852                        if ( ! empty( $exif['DateTimeOriginal'] ) ) {
     853                                $rawdate = $exif['DateTimeOriginal'];
     854                                if ( ! empty( $exif['UndefinedTag:0x9011'] ) ) {
     855                                        $timezone = new DateTimeZone( $exif['UndefinedTag:0x9011'] );
     856                                }
     857                        } elseif ( ! empty( $exif['DateTimeDigitized'] ) ) {
     858                                $rawdate = $exif['DateTimeDigitized'];
     859                                if ( ! empty( $exif['UndefinedTag:0x9012'] ) ) {
     860                                        $timezone = new DateTimeZone( $exif['UndefinedTag:0x9012'] );
     861                                }
     862                        }
     863                        if ( ! $timezone && $rawdate ) {
     864                                // Attempt to derive offset from the GPS Timestamp if set as this is set to UTC but may not reflect creation time
     865                                if ( ! empty( $exif['GPSTimeStamp'] ) && ! empty( $exif['GPSDateStamp'] ) ) {
     866                                        $gps = wp_exif_gpsdatetime( $exif['GPSDateStamp'], $exif['GPSTimeStamp'] );
     867                                        $offsetdatetime = wp_exif_datetime( $rawdate, '+0000' );
     868                                        $seconds = $offsetdatetime->getTimestamp() - $gps->getTimestamp();
     869                                        $timezone = new DateTimeZone( timezone_name_from_abbr( '', $seconds, 0 ) );
     870                                } else {
     871                                        // If no timezone can be found assume the site timezone
     872                                        $timezone = wp_timezone();
     873                                }
     874                        }
     875                        $datetime = wp_exif_datetime( $rawdate, $timezone );
     876
     877                        // Store as a RFC3339 formatted timestring as this includes both date, time, and timezone
     878                        $meta['created'] = $datetime->format( DATE_RFC3339 );
     879
     880                        // For backcompat set the timestamp
     881                        $meta['created_timestamp'] = $datetime->getTimestamp();
    818882                }
    819883                if ( ! empty( $exif['FocalLength'] ) ) {
    820884                        $meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );