%PDF- %PDF-
Direktori : /var/www/html/buggydubrovnik.com/wp-content/plugins/envira-gallery-lite/includes/admin/ |
Current File : /var/www/html/buggydubrovnik.com/wp-content/plugins/envira-gallery-lite/includes/admin/media.php |
<?php /** * Media class. * * @since 1.0.0 * * @package Envira_Gallery * @author Envira Gallery Team */ // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Media Helper Class * * @since 1.0.0 */ class Envira_Gallery_Media { /** * Holds the class object. * * @since 1.0.0 * * @var object */ public static $instance; /** * Path to the file. * * @since 1.0.0 * * @var string */ public $file = __FILE__; /** * Holds the base class object. * * @since 1.0.0 * * @var object */ public $base; /** * Primary class constructor. * * @since 1.0.0 */ public function __construct() { // Load the base class object. $this->base = Envira_Gallery_Lite::get_instance(); add_filter( 'wp_handle_upload', array( $this, 'fix_image_orientation' ) ); } /** * Check if the EXIF orientation flag matches one of the values we're looking for * http://www.impulseadventure.com/photo/exif-orientation.html * * If it does, this means we need to rotate the image based on the orientation flag and then remove the flag. * This will ensure the image has the correct orientation, regardless of where it's displayed. * * Whilst most browsers and applications will read this flag to perform the rotation on displaying just the image, it's * not possible to do this in some situations e.g. displaying an image within a lightbox, or when the image is * within HTML markup. * * Orientation flags we're looking for: * 8: We need to rotate the image 90 degrees counter-clockwise * 3: We need to rotate the image 180 degrees * 6: We need to rotate the image 90 degrees clockwise (270 degrees counter-clockwise) * * @since 1.3.8.2 * * @param array $file Uploaded File. * @return array Uploaded File. */ public function fix_image_orientation( $file ) { // Check we have a file. if ( ! file_exists( $file['file'] ) ) { return $file; } // Check we have a JPEG. if ( 'image/jpg' !== $file['type'] && 'image/jpeg' !== $file['type'] ) { return $file; } // Attempt to read EXIF data from the image. $exif_data = wp_read_image_metadata( $file['file'] ); if ( ! $exif_data ) { return $file; } // Check if an orientation flag exists. if ( ! isset( $exif_data['orientation'] ) ) { return $file; } // Check if the orientation flag matches one we're looking for. $required_orientations = array( 8, 3, 6 ); if ( ! in_array( $exif_data['orientation'], $required_orientations, true ) ) { return $file; } // If here, the orientation flag matches one we're looking for. // Load the WordPress Image Editor class. $image = wp_get_image_editor( $file['file'] ); if ( is_wp_error( $image ) ) { // Something went wrong - abort. return $file; } // Store the source image EXIF and IPTC data in a variable, which we'll write. // back to the image once its orientation has changed. // This is required because when we save an image, it'll lose its metadata. $source_size = getimagesize( $file['file'], $image_info ); // Depending on the orientation flag, rotate the image. switch ( $exif_data['orientation'] ) { /** * Rotate 90 degrees counter-clockwise. */ case 8: $image->rotate( 90 ); break; /** * Rotate 180 degrees. */ case 3: $image->rotate( 180 ); break; /** * Rotate 270 degrees counter-clockwise ($image->rotate always works counter-clockwise). */ case 6: $image->rotate( 270 ); break; } // Save the image, overwriting the existing image. // This will discard the EXIF and IPTC data. $image->save( $file['file'] ); // Drop the EXIF orientation flag, otherwise applications will try to rotate the image. // before display it, and we don't need that to happen as we've corrected the orientation. // Write the EXIF and IPTC metadata to the revised image. $result = $this->transfer_iptc_exif_to_image( $image_info, $file['file'], $exif_data['orientation'] ); if ( ! $result ) { return $file; } // Read the image again to see if the EXIF data was preserved. $exif_data = wp_read_image_metadata( $file['file'] ); // Finally, return the data that's expected. return $file; } /** * Transfers IPTC and EXIF data from a source image which contains either/both, * and saves it into a destination image's headers that might not have this IPTC * or EXIF data * * Useful for when you edit an image through PHP and need to preserve IPTC and EXIF * data * * @since 1.3.8.2 * * @source http://php.net/iptcembed - ebashkoff at gmail dot com * * @param string $image_info EXIF and IPTC image information from the source image, using getimagesize(). * @param string $destination_image Path and File of Destination Image, which needs IPTC and EXIF data. * @param int $original_orientation The image's original orientation, before we changed it. * Used when we replace this orientation in the EXIF data. * @return bool Success */ private function transfer_iptc_exif_to_image( $image_info, $destination_image, $original_orientation ) { // Check destination exists. if ( ! file_exists( $destination_image ) ) { return false; } // Get EXIF data from the image info, and create the IPTC segment. $exif_data = ( ( is_array( $image_info ) && key_exists( 'APP1', $image_info ) ) ? $image_info['APP1'] : null ); if ( $exif_data ) { // Find the image's original orientation flag, and change it to 1. // This prevents applications and browsers re-rotating the image, when we've already performed that function. $exif_data = str_replace( chr( dechex( $original_orientation ) ), chr( 0x1 ), $exif_data ); $exif_length = strlen( $exif_data ) + 2; if ( $exif_length > 0xFFFF ) { return false; } // Construct EXIF segment. $exif_data = chr( 0xFF ) . chr( 0xE1 ) . chr( ( $exif_length >> 8 ) & 0xFF ) . chr( $exif_length & 0xFF ) . $exif_data; } // Get IPTC data from the source image, and create the IPTC segment. $iptc_data = ( ( is_array( $image_info ) && key_exists( 'APP13', $image_info ) ) ? $image_info['APP13'] : null ); if ( $iptc_data ) { $iptc_length = strlen( $iptc_data ) + 2; if ( $iptc_length > 0xFFFF ) { return false; } // Construct IPTC segment. $iptc_data = chr( 0xFF ) . chr( 0xED ) . chr( ( $iptc_length >> 8 ) & 0xFF ) . chr( $iptc_length & 0xFF ) . $iptc_data; } // Get the contents of the destination image. $destination_image_contents = file_get_contents( $destination_image ); if ( ! $destination_image_contents ) { return false; } if ( strlen( $destination_image_contents ) === 0 ) { return false; } // Build the EXIF and IPTC data headers. $destination_image_contents = substr( $destination_image_contents, 2 ); $portion_to_add = chr( 0xFF ) . chr( 0xD8 ); // Variable accumulates new & original IPTC application segments. $exif_added = ! $exif_data; $iptc_added = ! $iptc_data; while ( ( substr( $destination_image_contents, 0, 2 ) && 0xFFF0 ) === 0xFFE0 ) { $segment_length = ( substr( $destination_image_contents, 2, 2 ) & 0xFFFF ); $iptc_segment_number = ( substr( $destination_image_contents, 1, 1 ) & 0x0F ); // Last 4 bits of second byte is IPTC segment #. if ( $segment_length <= 2 ) { return false; } $thisexistingsegment = substr( $destination_image_contents, 0, $segment_length + 2 ); if ( ( 1 <= $iptc_segment_number ) && ( ! $exif_added ) ) { $portion_to_add .= $exif_data; $exif_added = true; if ( 1 === $iptc_segment_number ) { $thisexistingsegment = ''; } } if ( ( 13 <= $iptc_segment_number ) && ( ! $iptc_added ) ) { $portion_to_add .= $iptc_data; $iptc_added = true; if ( 13 === $iptc_segment_number ) { $thisexistingsegment = ''; } } $portion_to_add .= $thisexistingsegment; $destination_image_contents = substr( $destination_image_contents, $segment_length + 2 ); } // Write the EXIF and IPTC data to the new file. if ( ! $exif_added ) { $portion_to_add .= $exif_data; } if ( ! $iptc_added ) { $portion_to_add .= $iptc_data; } $output_file = fopen( $destination_image, 'w' ); // @codingStandardsIgnoreLine - !!! TODO migrate to WP filesystem if ( $output_file ) { return fwrite( $output_file, $portion_to_add . $destination_image_contents ); // @codingStandardsIgnoreLine - !!! TODO migrate to WP filesystem } return false; } /** * Returns the singleton instance of the class. * * @since 1.0.0 * * @return object The Envira_Gallery_Media object. */ public static function get_instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Envira_Gallery_Media ) ) { self::$instance = new Envira_Gallery_Media(); } return self::$instance; } } // Load the media class. $envira_gallery_media = Envira_Gallery_Media::get_instance();