home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress2 / wp-admin / includes / image.php < prev    next >
Encoding:
PHP Script  |  2018-01-15  |  21.6 KB  |  700 lines

  1. <?php
  2. /**
  3.  * File contains all the administration image manipulation functions.
  4.  *
  5.  * @package WordPress
  6.  * @subpackage Administration
  7.  */
  8.  
  9. /**
  10.  * Crop an Image to a given size.
  11.  *
  12.  * @since 2.1.0
  13.  *
  14.  * @param string|int $src The source file or Attachment ID.
  15.  * @param int $src_x The start x position to crop from.
  16.  * @param int $src_y The start y position to crop from.
  17.  * @param int $src_w The width to crop.
  18.  * @param int $src_h The height to crop.
  19.  * @param int $dst_w The destination width.
  20.  * @param int $dst_h The destination height.
  21.  * @param int $src_abs Optional. If the source crop points are absolute.
  22.  * @param string $dst_file Optional. The destination file to write to.
  23.  * @return string|WP_Error New filepath on success, WP_Error on failure.
  24.  */
  25. function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) {
  26.     $src_file = $src;
  27.     if ( is_numeric( $src ) ) { // Handle int as attachment ID
  28.         $src_file = get_attached_file( $src );
  29.  
  30.         if ( ! file_exists( $src_file ) ) {
  31.             // If the file doesn't exist, attempt a URL fopen on the src link.
  32.             // This can occur with certain file replication plugins.
  33.             $src = _load_image_to_edit_path( $src, 'full' );
  34.         } else {
  35.             $src = $src_file;
  36.         }
  37.     }
  38.  
  39.     $editor = wp_get_image_editor( $src );
  40.     if ( is_wp_error( $editor ) )
  41.         return $editor;
  42.  
  43.     $src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );
  44.     if ( is_wp_error( $src ) )
  45.         return $src;
  46.  
  47.     if ( ! $dst_file )
  48.         $dst_file = str_replace( basename( $src_file ), 'cropped-' . basename( $src_file ), $src_file );
  49.  
  50.     /*
  51.      * The directory containing the original file may no longer exist when
  52.      * using a replication plugin.
  53.      */
  54.     wp_mkdir_p( dirname( $dst_file ) );
  55.  
  56.     $dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), basename( $dst_file ) );
  57.  
  58.     $result = $editor->save( $dst_file );
  59.     if ( is_wp_error( $result ) )
  60.         return $result;
  61.  
  62.     return $dst_file;
  63. }
  64.  
  65. /**
  66.  * Generate post thumbnail attachment meta data.
  67.  *
  68.  * @since 2.1.0
  69.  *
  70.  * @param int $attachment_id Attachment Id to process.
  71.  * @param string $file Filepath of the Attached image.
  72.  * @return mixed Metadata for attachment.
  73.  */
  74. function wp_generate_attachment_metadata( $attachment_id, $file ) {
  75.     $attachment = get_post( $attachment_id );
  76.  
  77.     $metadata = array();
  78.     $support = false;
  79.     $mime_type = get_post_mime_type( $attachment );
  80.  
  81.     if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
  82.         $imagesize = getimagesize( $file );
  83.         $metadata['width'] = $imagesize[0];
  84.         $metadata['height'] = $imagesize[1];
  85.  
  86.         // Make the file path relative to the upload dir.
  87.         $metadata['file'] = _wp_relative_upload_path($file);
  88.  
  89.         // Make thumbnails and other intermediate sizes.
  90.         $_wp_additional_image_sizes = wp_get_additional_image_sizes();
  91.  
  92.         $sizes = array();
  93.         foreach ( get_intermediate_image_sizes() as $s ) {
  94.             $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
  95.             if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) {
  96.                 // For theme-added sizes
  97.                 $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] );
  98.             } else {
  99.                 // For default sizes set in options
  100.                 $sizes[$s]['width'] = get_option( "{$s}_size_w" );
  101.             }
  102.  
  103.             if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) {
  104.                 // For theme-added sizes
  105.                 $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] );
  106.             } else {
  107.                 // For default sizes set in options
  108.                 $sizes[$s]['height'] = get_option( "{$s}_size_h" );
  109.             }
  110.  
  111.             if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) {
  112.                 // For theme-added sizes
  113.                 $sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
  114.             } else {
  115.                 // For default sizes set in options
  116.                 $sizes[$s]['crop'] = get_option( "{$s}_crop" );
  117.             }
  118.         }
  119.  
  120.         /**
  121.          * Filters the image sizes automatically generated when uploading an image.
  122.          *
  123.          * @since 2.9.0
  124.          * @since 4.4.0 Added the `$metadata` argument.
  125.          *
  126.          * @param array $sizes    An associative array of image sizes.
  127.          * @param array $metadata An associative array of image metadata: width, height, file.
  128.          */
  129.         $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata );
  130.  
  131.         if ( $sizes ) {
  132.             $editor = wp_get_image_editor( $file );
  133.  
  134.             if ( ! is_wp_error( $editor ) )
  135.                 $metadata['sizes'] = $editor->multi_resize( $sizes );
  136.         } else {
  137.             $metadata['sizes'] = array();
  138.         }
  139.  
  140.         // Fetch additional metadata from EXIF/IPTC.
  141.         $image_meta = wp_read_image_metadata( $file );
  142.         if ( $image_meta )
  143.             $metadata['image_meta'] = $image_meta;
  144.  
  145.     } elseif ( wp_attachment_is( 'video', $attachment ) ) {
  146.         $metadata = wp_read_video_metadata( $file );
  147.         $support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
  148.     } elseif ( wp_attachment_is( 'audio', $attachment ) ) {
  149.         $metadata = wp_read_audio_metadata( $file );
  150.         $support = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
  151.     }
  152.  
  153.     if ( $support && ! empty( $metadata['image']['data'] ) ) {
  154.         // Check for existing cover.
  155.         $hash = md5( $metadata['image']['data'] );
  156.         $posts = get_posts( array(
  157.             'fields' => 'ids',
  158.             'post_type' => 'attachment',
  159.             'post_mime_type' => $metadata['image']['mime'],
  160.             'post_status' => 'inherit',
  161.             'posts_per_page' => 1,
  162.             'meta_key' => '_cover_hash',
  163.             'meta_value' => $hash
  164.         ) );
  165.         $exists = reset( $posts );
  166.  
  167.         if ( ! empty( $exists ) ) {
  168.             update_post_meta( $attachment_id, '_thumbnail_id', $exists );
  169.         } else {
  170.             $ext = '.jpg';
  171.             switch ( $metadata['image']['mime'] ) {
  172.             case 'image/gif':
  173.                 $ext = '.gif';
  174.                 break;
  175.             case 'image/png':
  176.                 $ext = '.png';
  177.                 break;
  178.             }
  179.             $basename = str_replace( '.', '-', basename( $file ) ) . '-image' . $ext;
  180.             $uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
  181.             if ( false === $uploaded['error'] ) {
  182.                 $image_attachment = array(
  183.                     'post_mime_type' => $metadata['image']['mime'],
  184.                     'post_type' => 'attachment',
  185.                     'post_content' => '',
  186.                 );
  187.                 /**
  188.                  * Filters the parameters for the attachment thumbnail creation.
  189.                  *
  190.                  * @since 3.9.0
  191.                  *
  192.                  * @param array $image_attachment An array of parameters to create the thumbnail.
  193.                  * @param array $metadata         Current attachment metadata.
  194.                  * @param array $uploaded         An array containing the thumbnail path and url.
  195.                  */
  196.                 $image_attachment = apply_filters( 'attachment_thumbnail_args', $image_attachment, $metadata, $uploaded );
  197.  
  198.                 $sub_attachment_id = wp_insert_attachment( $image_attachment, $uploaded['file'] );
  199.                 add_post_meta( $sub_attachment_id, '_cover_hash', $hash );
  200.                 $attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
  201.                 wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
  202.                 update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
  203.             }
  204.         }
  205.     }
  206.     // Try to create image thumbnails for PDFs
  207.     else if ( 'application/pdf' === $mime_type ) {
  208.         $fallback_sizes = array(
  209.             'thumbnail',
  210.             'medium',
  211.             'large',
  212.         );
  213.  
  214.         /**
  215.          * Filters the image sizes generated for non-image mime types.
  216.          *
  217.          * @since 4.7.0
  218.          *
  219.          * @param array $fallback_sizes An array of image size names.
  220.          * @param array $metadata       Current attachment metadata.
  221.          */
  222.         $fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
  223.  
  224.         $sizes = array();
  225.         $_wp_additional_image_sizes = wp_get_additional_image_sizes();
  226.  
  227.         foreach ( $fallback_sizes as $s ) {
  228.             if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
  229.                 $sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
  230.             } else {
  231.                 $sizes[ $s ]['width'] = get_option( "{$s}_size_w" );
  232.             }
  233.  
  234.             if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
  235.                 $sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );
  236.             } else {
  237.                 $sizes[ $s ]['height'] = get_option( "{$s}_size_h" );
  238.             }
  239.  
  240.             if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
  241.                 $sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];
  242.             } else {
  243.                 // Force thumbnails to be soft crops.
  244.                 if ( ! 'thumbnail' === $s ) {
  245.                     $sizes[ $s ]['crop'] = get_option( "{$s}_crop" );
  246.                 }
  247.             }
  248.         }
  249.  
  250.         // Only load PDFs in an image editor if we're processing sizes.
  251.         if ( ! empty( $sizes ) ) {
  252.             $editor = wp_get_image_editor( $file );
  253.  
  254.             if ( ! is_wp_error( $editor ) ) { // No support for this type of file
  255.                 /*
  256.                  * PDFs may have the same file filename as JPEGs.
  257.                  * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
  258.                  */
  259.                 $dirname = dirname( $file ) . '/';
  260.                 $ext = '.' . pathinfo( $file, PATHINFO_EXTENSION );
  261.                 $preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
  262.  
  263.                 $uploaded = $editor->save( $preview_file, 'image/jpeg' );
  264.                 unset( $editor );
  265.  
  266.                 // Resize based on the full size image, rather than the source.
  267.                 if ( ! is_wp_error( $uploaded ) ) {
  268.                     $editor = wp_get_image_editor( $uploaded['path'] );
  269.                     unset( $uploaded['path'] );
  270.  
  271.                     if ( ! is_wp_error( $editor ) ) {
  272.                         $metadata['sizes'] = $editor->multi_resize( $sizes );
  273.                         $metadata['sizes']['full'] = $uploaded;
  274.                     }
  275.                 }
  276.             }
  277.         }
  278.     }
  279.  
  280.     // Remove the blob of binary data from the array.
  281.     if ( $metadata ) {
  282.         unset( $metadata['image']['data'] );
  283.     }
  284.  
  285.     /**
  286.      * Filters the generated attachment meta data.
  287.      *
  288.      * @since 2.1.0
  289.      *
  290.      * @param array $metadata      An array of attachment meta data.
  291.      * @param int   $attachment_id Current attachment ID.
  292.      */
  293.     return apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id );
  294. }
  295.  
  296. /**
  297.  * Convert a fraction string to a decimal.
  298.  *
  299.  * @since 2.5.0
  300.  *
  301.  * @param string $str
  302.  * @return int|float
  303.  */
  304. function wp_exif_frac2dec($str) {
  305.     @list( $n, $d ) = explode( '/', $str );
  306.     if ( !empty($d) )
  307.         return $n / $d;
  308.     return $str;
  309. }
  310.  
  311. /**
  312.  * Convert the exif date format to a unix timestamp.
  313.  *
  314.  * @since 2.5.0
  315.  *
  316.  * @param string $str
  317.  * @return int
  318.  */
  319. function wp_exif_date2ts($str) {
  320.     @list( $date, $time ) = explode( ' ', trim($str) );
  321.     @list( $y, $m, $d ) = explode( ':', $date );
  322.  
  323.     return strtotime( "{$y}-{$m}-{$d} {$time}" );
  324. }
  325.  
  326. /**
  327.  * Get extended image metadata, exif or iptc as available.
  328.  *
  329.  * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso
  330.  * created_timestamp, focal_length, shutter_speed, and title.
  331.  *
  332.  * The IPTC metadata that is retrieved is APP13, credit, byline, created date
  333.  * and time, caption, copyright, and title. Also includes FNumber, Model,
  334.  * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime.
  335.  *
  336.  * @todo Try other exif libraries if available.
  337.  * @since 2.5.0
  338.  *
  339.  * @param string $file
  340.  * @return bool|array False on failure. Image metadata array on success.
  341.  */
  342. function wp_read_image_metadata( $file ) {
  343.     if ( ! file_exists( $file ) )
  344.         return false;
  345.  
  346.     list( , , $sourceImageType ) = @getimagesize( $file );
  347.  
  348.     /*
  349.      * EXIF contains a bunch of data we'll probably never need formatted in ways
  350.      * that are difficult to use. We'll normalize it and just extract the fields
  351.      * that are likely to be useful. Fractions and numbers are converted to
  352.      * floats, dates to unix timestamps, and everything else to strings.
  353.      */
  354.     $meta = array(
  355.         'aperture' => 0,
  356.         'credit' => '',
  357.         'camera' => '',
  358.         'caption' => '',
  359.         'created_timestamp' => 0,
  360.         'copyright' => '',
  361.         'focal_length' => 0,
  362.         'iso' => 0,
  363.         'shutter_speed' => 0,
  364.         'title' => '',
  365.         'orientation' => 0,
  366.         'keywords' => array(),
  367.     );
  368.  
  369.     $iptc = array();
  370.     /*
  371.      * Read IPTC first, since it might contain data not available in exif such
  372.      * as caption, description etc.
  373.      */
  374.     if ( is_callable( 'iptcparse' ) ) {
  375.         @getimagesize( $file, $info );
  376.  
  377.         if ( ! empty( $info['APP13'] ) ) {
  378.             $iptc = @iptcparse( $info['APP13'] );
  379.  
  380.             // Headline, "A brief synopsis of the caption."
  381.             if ( ! empty( $iptc['2#105'][0] ) ) {
  382.                 $meta['title'] = trim( $iptc['2#105'][0] );
  383.             /*
  384.              * Title, "Many use the Title field to store the filename of the image,
  385.              * though the field may be used in many ways."
  386.              */
  387.             } elseif ( ! empty( $iptc['2#005'][0] ) ) {
  388.                 $meta['title'] = trim( $iptc['2#005'][0] );
  389.             }
  390.  
  391.             if ( ! empty( $iptc['2#120'][0] ) ) { // description / legacy caption
  392.                 $caption = trim( $iptc['2#120'][0] );
  393.  
  394.                 mbstring_binary_safe_encoding();
  395.                 $caption_length = strlen( $caption );
  396.                 reset_mbstring_encoding();
  397.  
  398.                 if ( empty( $meta['title'] ) && $caption_length < 80 ) {
  399.                     // Assume the title is stored in 2:120 if it's short.
  400.                     $meta['title'] = $caption;
  401.                 }
  402.  
  403.                 $meta['caption'] = $caption;
  404.             }
  405.  
  406.             if ( ! empty( $iptc['2#110'][0] ) ) // credit
  407.                 $meta['credit'] = trim( $iptc['2#110'][0] );
  408.             elseif ( ! empty( $iptc['2#080'][0] ) ) // creator / legacy byline
  409.                 $meta['credit'] = trim( $iptc['2#080'][0] );
  410.  
  411.             if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) // created date and time
  412.                 $meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
  413.  
  414.             if ( ! empty( $iptc['2#116'][0] ) ) // copyright
  415.                 $meta['copyright'] = trim( $iptc['2#116'][0] );
  416.  
  417.             if ( ! empty( $iptc['2#025'][0] ) ) { // keywords array
  418.                 $meta['keywords'] = array_values( $iptc['2#025'] );
  419.             }
  420.          }
  421.     }
  422.  
  423.     /**
  424.      * Filters the image types to check for exif data.
  425.      *
  426.      * @since 2.5.0
  427.      *
  428.      * @param array $image_types Image types to check for exif data.
  429.      */
  430.     if ( is_callable( 'exif_read_data' ) && in_array( $sourceImageType, apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ) ) ) {
  431.         $exif = @exif_read_data( $file );
  432.  
  433.         if ( ! empty( $exif['ImageDescription'] ) ) {
  434.             mbstring_binary_safe_encoding();
  435.             $description_length = strlen( $exif['ImageDescription'] );
  436.             reset_mbstring_encoding();
  437.  
  438.             if ( empty( $meta['title'] ) && $description_length < 80 ) {
  439.                 // Assume the title is stored in ImageDescription
  440.                 $meta['title'] = trim( $exif['ImageDescription'] );
  441.             }
  442.  
  443.             if ( empty( $meta['caption'] ) && ! empty( $exif['COMPUTED']['UserComment'] ) ) {
  444.                 $meta['caption'] = trim( $exif['COMPUTED']['UserComment'] );
  445.             }
  446.  
  447.             if ( empty( $meta['caption'] ) ) {
  448.                 $meta['caption'] = trim( $exif['ImageDescription'] );
  449.             }
  450.         } elseif ( empty( $meta['caption'] ) && ! empty( $exif['Comments'] ) ) {
  451.             $meta['caption'] = trim( $exif['Comments'] );
  452.         }
  453.  
  454.         if ( empty( $meta['credit'] ) ) {
  455.             if ( ! empty( $exif['Artist'] ) ) {
  456.                 $meta['credit'] = trim( $exif['Artist'] );
  457.             } elseif ( ! empty($exif['Author'] ) ) {
  458.                 $meta['credit'] = trim( $exif['Author'] );
  459.             }
  460.         }
  461.  
  462.         if ( empty( $meta['copyright'] ) && ! empty( $exif['Copyright'] ) ) {
  463.             $meta['copyright'] = trim( $exif['Copyright'] );
  464.         }
  465.         if ( ! empty( $exif['FNumber'] ) ) {
  466.             $meta['aperture'] = round( wp_exif_frac2dec( $exif['FNumber'] ), 2 );
  467.         }
  468.         if ( ! empty( $exif['Model'] ) ) {
  469.             $meta['camera'] = trim( $exif['Model'] );
  470.         }
  471.         if ( empty( $meta['created_timestamp'] ) && ! empty( $exif['DateTimeDigitized'] ) ) {
  472.             $meta['created_timestamp'] = wp_exif_date2ts( $exif['DateTimeDigitized'] );
  473.         }
  474.         if ( ! empty( $exif['FocalLength'] ) ) {
  475.             $meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );
  476.         }
  477.         if ( ! empty( $exif['ISOSpeedRatings'] ) ) {
  478.             $meta['iso'] = is_array( $exif['ISOSpeedRatings'] ) ? reset( $exif['ISOSpeedRatings'] ) : $exif['ISOSpeedRatings'];
  479.             $meta['iso'] = trim( $meta['iso'] );
  480.         }
  481.         if ( ! empty( $exif['ExposureTime'] ) ) {
  482.             $meta['shutter_speed'] = (string) wp_exif_frac2dec( $exif['ExposureTime'] );
  483.         }
  484.         if ( ! empty( $exif['Orientation'] ) ) {
  485.             $meta['orientation'] = $exif['Orientation'];
  486.         }
  487.     }
  488.  
  489.     foreach ( array( 'title', 'caption', 'credit', 'copyright', 'camera', 'iso' ) as $key ) {
  490.         if ( $meta[ $key ] && ! seems_utf8( $meta[ $key ] ) ) {
  491.             $meta[ $key ] = utf8_encode( $meta[ $key ] );
  492.         }
  493.     }
  494.  
  495.     foreach ( $meta['keywords'] as $key => $keyword ) {
  496.         if ( ! seems_utf8( $keyword ) ) {
  497.             $meta['keywords'][ $key ] = utf8_encode( $keyword );
  498.         }
  499.     }
  500.  
  501.     $meta = wp_kses_post_deep( $meta );
  502.  
  503.     /**
  504.      * Filters the array of meta data read from an image's exif data.
  505.      *
  506.      * @since 2.5.0
  507.      * @since 4.4.0 The `$iptc` parameter was added.
  508.      *
  509.      * @param array  $meta            Image meta data.
  510.      * @param string $file            Path to image file.
  511.      * @param int    $sourceImageType Type of image.
  512.      * @param array  $iptc            IPTC data.
  513.      */
  514.     return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType, $iptc );
  515.  
  516. }
  517.  
  518. /**
  519.  * Validate that file is an image.
  520.  *
  521.  * @since 2.5.0
  522.  *
  523.  * @param string $path File path to test if valid image.
  524.  * @return bool True if valid image, false if not valid image.
  525.  */
  526. function file_is_valid_image($path) {
  527.     $size = @getimagesize($path);
  528.     return !empty($size);
  529. }
  530.  
  531. /**
  532.  * Validate that file is suitable for displaying within a web page.
  533.  *
  534.  * @since 2.5.0
  535.  *
  536.  * @param string $path File path to test.
  537.  * @return bool True if suitable, false if not suitable.
  538.  */
  539. function file_is_displayable_image($path) {
  540.     $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP );
  541.  
  542.     $info = @getimagesize( $path );
  543.     if ( empty( $info ) ) {
  544.         $result = false;
  545.     } elseif ( ! in_array( $info[2], $displayable_image_types ) ) {
  546.         $result = false;
  547.     } else {
  548.         $result = true;
  549.     }
  550.  
  551.     /**
  552.      * Filters whether the current image is displayable in the browser.
  553.      *
  554.      * @since 2.5.0
  555.      *
  556.      * @param bool   $result Whether the image can be displayed. Default true.
  557.      * @param string $path   Path to the image.
  558.      */
  559.     return apply_filters( 'file_is_displayable_image', $result, $path );
  560. }
  561.  
  562. /**
  563.  * Load an image resource for editing.
  564.  *
  565.  * @since 2.9.0
  566.  *
  567.  * @param string $attachment_id Attachment ID.
  568.  * @param string $mime_type Image mime type.
  569.  * @param string $size Optional. Image size, defaults to 'full'.
  570.  * @return resource|false The resulting image resource on success, false on failure.
  571.  */
  572. function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
  573.     $filepath = _load_image_to_edit_path( $attachment_id, $size );
  574.     if ( empty( $filepath ) )
  575.         return false;
  576.  
  577.     switch ( $mime_type ) {
  578.         case 'image/jpeg':
  579.             $image = imagecreatefromjpeg($filepath);
  580.             break;
  581.         case 'image/png':
  582.             $image = imagecreatefrompng($filepath);
  583.             break;
  584.         case 'image/gif':
  585.             $image = imagecreatefromgif($filepath);
  586.             break;
  587.         default:
  588.             $image = false;
  589.             break;
  590.     }
  591.     if ( is_resource($image) ) {
  592.         /**
  593.          * Filters the current image being loaded for editing.
  594.          *
  595.          * @since 2.9.0
  596.          *
  597.          * @param resource $image         Current image.
  598.          * @param string   $attachment_id Attachment ID.
  599.          * @param string   $size          Image size.
  600.          */
  601.         $image = apply_filters( 'load_image_to_edit', $image, $attachment_id, $size );
  602.         if ( function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
  603.             imagealphablending($image, false);
  604.             imagesavealpha($image, true);
  605.         }
  606.     }
  607.     return $image;
  608. }
  609.  
  610. /**
  611.  * Retrieve the path or url of an attachment's attached file.
  612.  *
  613.  * If the attached file is not present on the local filesystem (usually due to replication plugins),
  614.  * then the url of the file is returned if url fopen is supported.
  615.  *
  616.  * @since 3.4.0
  617.  * @access private
  618.  *
  619.  * @param string $attachment_id Attachment ID.
  620.  * @param string $size Optional. Image size, defaults to 'full'.
  621.  * @return string|false File path or url on success, false on failure.
  622.  */
  623. function _load_image_to_edit_path( $attachment_id, $size = 'full' ) {
  624.     $filepath = get_attached_file( $attachment_id );
  625.  
  626.     if ( $filepath && file_exists( $filepath ) ) {
  627.         if ( 'full' != $size && ( $data = image_get_intermediate_size( $attachment_id, $size ) ) ) {
  628.             /**
  629.              * Filters the path to the current image.
  630.              *
  631.              * The filter is evaluated for all image sizes except 'full'.
  632.              *
  633.              * @since 3.1.0
  634.              *
  635.              * @param string $path          Path to the current image.
  636.              * @param string $attachment_id Attachment ID.
  637.              * @param string $size          Size of the image.
  638.              */
  639.             $filepath = apply_filters( 'load_image_to_edit_filesystempath', path_join( dirname( $filepath ), $data['file'] ), $attachment_id, $size );
  640.         }
  641.     } elseif ( function_exists( 'fopen' ) && true == ini_get( 'allow_url_fopen' ) ) {
  642.         /**
  643.          * Filters the image URL if not in the local filesystem.
  644.          *
  645.          * The filter is only evaluated if fopen is enabled on the server.
  646.          *
  647.          * @since 3.1.0
  648.          *
  649.          * @param string $image_url     Current image URL.
  650.          * @param string $attachment_id Attachment ID.
  651.          * @param string $size          Size of the image.
  652.          */
  653.         $filepath = apply_filters( 'load_image_to_edit_attachmenturl', wp_get_attachment_url( $attachment_id ), $attachment_id, $size );
  654.     }
  655.  
  656.     /**
  657.      * Filters the returned path or URL of the current image.
  658.      *
  659.      * @since 2.9.0
  660.      *
  661.      * @param string|bool $filepath      File path or URL to current image, or false.
  662.      * @param string      $attachment_id Attachment ID.
  663.      * @param string      $size          Size of the image.
  664.      */
  665.     return apply_filters( 'load_image_to_edit_path', $filepath, $attachment_id, $size );
  666. }
  667.  
  668. /**
  669.  * Copy an existing image file.
  670.  *
  671.  * @since 3.4.0
  672.  * @access private
  673.  *
  674.  * @param string $attachment_id Attachment ID.
  675.  * @return string|false New file path on success, false on failure.
  676.  */
  677. function _copy_image_file( $attachment_id ) {
  678.     $dst_file = $src_file = get_attached_file( $attachment_id );
  679.     if ( ! file_exists( $src_file ) )
  680.         $src_file = _load_image_to_edit_path( $attachment_id );
  681.  
  682.     if ( $src_file ) {
  683.         $dst_file = str_replace( basename( $dst_file ), 'copy-' . basename( $dst_file ), $dst_file );
  684.         $dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), basename( $dst_file ) );
  685.  
  686.         /*
  687.          * The directory containing the original file may no longer
  688.          * exist when using a replication plugin.
  689.          */
  690.         wp_mkdir_p( dirname( $dst_file ) );
  691.  
  692.         if ( ! @copy( $src_file, $dst_file ) )
  693.             $dst_file = false;
  694.     } else {
  695.         $dst_file = false;
  696.     }
  697.  
  698.     return $dst_file;
  699. }
  700.