WordPress.org

Make WordPress Core

Changeset 22817


Ignore:
Timestamp:
11/22/2012 09:52:16 AM (6 years ago)
Author:
nacin
Message:

WP_Image_Editor: the last stand.

  • Have wp_get_image_editor() rather than WP_Image_Editor::get_instance(). Having static factory methods would be less confusing if there weren't also static methods tied to individual editor implementations.
  • Lazy-load the WP_Image_Editor base class and editor implementations.
  • Have WP_Image_Editor_GD::supports_mime_type() actually check which types it supports.
  • Deprecate gd_edit_image_support() in favor of wp_image_editor_supports().

props DH-Shredder, scribu, markoheijnen. fixes #22356. see #6821.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/image-edit.php

    r22807 r22817  
    458458    @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
    459459
    460     $img = WP_Image_Editor::get_instance( _load_image_to_edit_path( $post_id ) );
     460    $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) );
    461461
    462462    if ( is_wp_error( $img ) )
     
    567567    $post = get_post( $post_id );
    568568
    569     $img = WP_Image_Editor::get_instance( _load_image_to_edit_path( $post_id, 'full' ) );
     569    $img = wp_get_image_editor( _load_image_to_edit_path( $post_id, 'full' ) );
    570570    if ( is_wp_error( $img ) ) {
    571571        $return->error = esc_js( __('Unable to create new image.') );
  • trunk/wp-admin/includes/image.php

    r22571 r22817  
    3737    }
    3838
    39     $editor = WP_Image_Editor::get_instance( $src );
     39    $editor = wp_get_image_editor( $src );
    4040    if ( is_wp_error( $editor ) )
    4141        return $editor;
     
    101101
    102102        if ( $sizes ) {
    103             $editor = WP_Image_Editor::get_instance( $file );
     103            $editor = wp_get_image_editor( $file );
    104104
    105105            if ( ! is_wp_error( $editor ) )
  • trunk/wp-admin/includes/media.php

    r22807 r22817  
    11231123
    11241124    $image_edit_button = '';
    1125     if ( gd_edit_image_support( $post->post_mime_type ) ) {
     1125    if ( wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
    11261126        $nonce = wp_create_nonce( "image_editor-$post->ID" );
    11271127        $image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
     
    22542254
    22552255    $image_edit_button = '';
    2256     if ( gd_edit_image_support( $post->post_mime_type ) ) {
     2256    if ( wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
    22572257        $nonce = wp_create_nonce( "image_editor-$post->ID" );
    22582258        $image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
  • trunk/wp-includes/class-wp-image-editor-gd.php

    r22619 r22817  
    1616 */
    1717class WP_Image_Editor_GD extends WP_Image_Editor {
     18
    1819    protected $image = false; // GD Resource
    1920
     
    3334     * @return boolean
    3435     */
    35     public static function test( $args = null ) {
     36    public static function test( $args = array() ) {
    3637        if ( ! extension_loaded('gd') || ! function_exists('gd_info') )
    3738            return false;
     
    4142
    4243    /**
     44     * Checks to see if editor supports the mime-type specified.
     45     *
     46     * @since 3.5.0
     47     * @access public
     48     *
     49     * @param string $mime_type
     50     * @return boolean
     51     */
     52    public static function supports_mime_type( $mime_type ) {
     53        $image_types = imagetypes();
     54        switch( $mime_type ) {
     55            case 'image/jpeg':
     56                return ($image_types & IMG_JPG) != 0;
     57            case 'image/png':
     58                return ($image_types & IMG_PNG) != 0;
     59            case 'image/gif':
     60                return ($image_types & IMG_GIF) != 0;
     61        }
     62
     63        return false;
     64    }
     65
     66    /**
    4367     * Loads image from $this->file into new GD Resource.
    4468     *
     
    4872     * @return boolean|\WP_Error
    4973     */
    50     protected function load() {
     74    public function load() {
    5175        if ( $this->image )
    5276            return true;
     
    89113
    90114        return parent::update_size( $width, $height );
    91     }
    92 
    93     /**
    94      * Checks to see if editor supports the mime-type specified.
    95      *
    96      * @since 3.5.0
    97      * @access public
    98      *
    99      * @param string $mime_type
    100      * @return boolean
    101      */
    102     public static function supports_mime_type( $mime_type ) {
    103         $allowed_mime_types = array( 'image/gif', 'image/png', 'image/jpeg' );
    104 
    105         return in_array( $mime_type, $allowed_mime_types );
    106115    }
    107116
     
    262271     * @access public
    263272     *
    264      * @param boolean $horz Horizonal Flip
     273     * @param boolean $horz Horizontal Flip
    265274     * @param boolean $vert Vertical Flip
    266275     * @returns boolean|WP_Error
  • trunk/wp-includes/class-wp-image-editor-imagick.php

    r22619 r22817  
    1616 */
    1717class WP_Image_Editor_Imagick extends WP_Image_Editor {
     18
    1819    protected $image = null; // Imagick Object
    1920
     
    3738     * @return boolean
    3839     */
    39     public static function test( $args = null ) {
     40    public static function test( $args = array() ) {
    4041        if ( ! extension_loaded( 'imagick' ) || ! is_callable( 'Imagick', 'queryFormats' ) )
    4142            return false;
     
    4546
    4647    /**
     48     * Checks to see if editor supports the mime-type specified.
     49     *
     50     * @since 3.5.0
     51     * @access public
     52     *
     53     * @param string $mime_type
     54     * @return boolean
     55     */
     56    public static function supports_mime_type( $mime_type ) {
     57        $imagick_extension = strtoupper( self::get_extension( $mime_type ) );
     58
     59        if ( ! $imagick_extension )
     60            return false;
     61
     62        try {
     63            return ( (bool) Imagick::queryFormats( $imagick_extension ) );
     64        }
     65        catch ( Exception $e ) {
     66            return false;
     67        }
     68    }
     69
     70    /**
    4771     * Loads image from $this->file into new Imagick Object.
    4872     *
     
    5276     * @return boolean|WP_Error True if loaded; WP_Error on failure.
    5377     */
    54     protected function load() {
     78    public function load() {
    5579        if ( $this->image )
    5680            return true;
     
    136160
    137161        return parent::update_size( $width, $height );
    138     }
    139 
    140     /**
    141      * Checks to see if editor supports the mime-type specified.
    142      *
    143      * @since 3.5.0
    144      * @access public
    145      *
    146      * @param string $mime_type
    147      * @return boolean
    148      */
    149     public static function supports_mime_type( $mime_type ) {
    150         if ( ! $mime_type )
    151             return false;
    152 
    153         $imagick_extension = strtoupper( self::get_extension( $mime_type ) );
    154 
    155         try {
    156             return ( (bool) Imagick::queryFormats( $imagick_extension ) );
    157         }
    158         catch ( Exception $e ) {
    159             return false;
    160         }
    161162    }
    162163
     
    313314     * @access public
    314315     *
    315      * @param boolean $horz Horizonal Flip
     316     * @param boolean $horz Horizontal Flip
    316317     * @param boolean $vert Vertical Flip
    317318     * @returns boolean|WP_Error
  • trunk/wp-includes/class-wp-image-editor.php

    r22619 r22817  
    88
    99/**
    10  * Base WordPress Image Editor class for which Editor implementations extend
     10 * Base image editor class from which implementations extend
    1111 *
    1212 * @since 3.5.0
     
    1515    protected $file = null;
    1616    protected $size = null;
    17     protected $mime_type  = null;
     17    protected $mime_type = null;
    1818    protected $default_mime_type = 'image/jpeg';
    1919    protected $quality = 90;
    2020
    21     protected function __construct( $filename ) {
    22         $this->file = $filename;
    23     }
    24 
    25     /**
    26      * Returns a WP_Image_Editor instance and loads file into it.
    27      *
    28      * @since 3.5.0
    29      * @access public
    30      *
    31      * @param string $path Path to File to Load
    32      * @param array $required_methods Methods to require in implementation
    33      * @return WP_Image_Editor|WP_Error
    34      */
    35     public final static function get_instance( $path = null, $required_methods = null ) {
    36         $implementation = apply_filters( 'wp_image_editor_class', self::choose_implementation( $required_methods ), $path );
    37 
    38         if ( $implementation ) {
    39             $editor = new $implementation( $path );
    40             $loaded = $editor->load();
    41 
    42             if ( is_wp_error( $loaded ) )
    43                 return $loaded;
    44 
    45             return $editor;
    46         }
    47 
    48         return new WP_Error( 'no_editor', __('No editor could be selected') );
    49     }
    50 
    51     /**
    52      * Tests which editors are capable of supporting the request.
    53      *
    54      * @since 3.5.0
    55      * @access private
    56      *
    57      * @param array $required_methods String array of all methods required for implementation returned.
    58      * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request.
    59      */
    60     private final static function choose_implementation( $required_methods = null ) {
    61         $request_order = apply_filters( 'wp_image_editors',
    62             array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
    63 
    64         if ( ! $required_methods )
    65             $required_methods = array();
    66 
    67         // Loop over each editor on each request looking for one which will serve this request's needs
    68         foreach ( $request_order as $editor ) {
    69             // Check to see if this editor is a possibility, calls the editor statically
    70             if ( ! call_user_func( array( $editor, 'test' ) ) )
    71                 continue;
    72 
    73             // Make sure that all methods are supported by editor.
    74             if ( array_diff( $required_methods, get_class_methods( $editor ) ) )
    75                 continue;
    76 
    77             return $editor;
    78         }
     21    /**
     22     * Each instance handles a single file.
     23     */
     24    public function __construct( $file ) {
     25        $this->file = $file;
     26    }
     27
     28    /**
     29     * Checks to see if current environment supports the editor chosen.
     30     * Must be overridden in a sub-class.
     31     *
     32     * @since 3.5.0
     33     * @access public
     34     * @abstract
     35     *
     36     * @param array $args
     37     * @return boolean
     38     */
     39    public static function test( $args = array() ) {
    7940        return false;
    8041    }
    8142
    8243    /**
     44     * Checks to see if editor supports the mime-type specified.
     45     * Must be overridden in a sub-class.
     46     *
     47     * @since 3.5.0
     48     * @access public
     49     * @abstract
     50     *
     51     * @param string $mime_type
     52     * @return boolean
     53     */
     54    public static function supports_mime_type( $mime_type ) {
     55        return false;
     56    }
     57
     58    /**
    8359     * Loads image from $this->file into editor.
    8460     *
     
    8965     * @return boolean|WP_Error True if loaded; WP_Error on failure.
    9066     */
    91     abstract protected function load();
     67    abstract public function load();
    9268
    9369    /**
     
    169145     * @abstract
    170146     *
    171      * @param boolean $horz Horizonal Flip
     147     * @param boolean $horz Horizontal Flip
    172148     * @param boolean $vert Vertical Flip
    173149     * @return boolean|WP_Error
     
    186162     */
    187163    abstract public function stream( $mime_type = null );
    188 
    189     /**
    190      * Checks to see if current environment supports the editor chosen.
    191      * Must be overridden in a sub-class.
    192      *
    193      * @since 3.5.0
    194      * @access public
    195      * @abstract
    196      *
    197      * @param array $args
    198      * @return boolean
    199      */
    200     public static function test( $args = null ) {
    201         return false;
    202     }
    203 
    204     /**
    205      * Checks to see if editor supports the mime-type specified.
    206      * Must be overridden in a sub-class.
    207      *
    208      * @since 3.5.0
    209      * @access public
    210      * @abstract
    211      *
    212      * @param string $mime_type
    213      * @return boolean
    214      */
    215     public static function supports_mime_type( $mime_type ) {
    216         return false;
    217     }
    218164
    219165    /**
     
    452398    }
    453399}
     400
  • trunk/wp-includes/deprecated.php

    r22463 r22817  
    32113211 * @since 2.1.0
    32123212 * @deprecated 3.5.0
    3213  * @see WP_Image_Editor
     3213 * @see wp_get_image_editor()
    32143214 *
    32153215 * @param string $file Filename of the image to load.
     
    32173217 */
    32183218function wp_load_image( $file ) {
    3219     _deprecated_function( __FUNCTION__, '3.5', 'WP_Image_Editor' );
     3219    _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_editor()' );
    32203220
    32213221    if ( is_numeric( $file ) )
     
    32513251 * @since 2.5.0
    32523252 * @deprecated 3.5.0
    3253  * @see WP_Image_Editor
     3253 * @see wp_get_image_editor()
    32543254 *
    32553255 * @param string $file Image file path.
     
    32633263 */
    32643264function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
    3265     _deprecated_function( __FUNCTION__, '3.5', 'WP_Image_Editor' );
    3266 
    3267     $editor = WP_Image_Editor::get_instance( $file );
     3265    _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_editor()' );
     3266
     3267    $editor = wp_get_image_editor( $file );
    32683268    if ( is_wp_error( $editor ) )
    32693269        return $editor;
     
    33303330 */
    33313331function _save_post_hook() {}
     3332
     3333/**
     3334 * Check if the installed version of GD supports particular image type
     3335 *
     3336 * @since 2.9.0
     3337 * @deprecated 3.5.0
     3338 * see wp_image_editor_supports()
     3339 *
     3340 * @param string $mime_type
     3341 * @return bool
     3342 */
     3343function gd_edit_image_support($mime_type) {
     3344    _deprecated_function( __FUNCTION__, '3.5', 'wp_image_editor_supports()' );
     3345
     3346    if ( function_exists('imagetypes') ) {
     3347        switch( $mime_type ) {
     3348            case 'image/jpeg':
     3349                return (imagetypes() & IMG_JPG) != 0;
     3350            case 'image/png':
     3351                return (imagetypes() & IMG_PNG) != 0;
     3352            case 'image/gif':
     3353                return (imagetypes() & IMG_GIF) != 0;
     3354        }
     3355    } else {
     3356        switch( $mime_type ) {
     3357            case 'image/jpeg':
     3358                return function_exists('imagecreatefromjpeg');
     3359            case 'image/png':
     3360                return function_exists('imagecreatefrompng');
     3361            case 'image/gif':
     3362                return function_exists('imagecreatefromgif');
     3363        }
     3364    }
     3365    return false;
     3366}
  • trunk/wp-includes/media.php

    r22816 r22817  
    384384function image_make_intermediate_size( $file, $width, $height, $crop = false ) {
    385385    if ( $width || $height ) {
    386         $editor = WP_Image_Editor::get_instance( $file );
     386        $editor = wp_get_image_editor( $file );
    387387
    388388        if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) )
     
    905905
    906906/**
    907  * Check if the installed version of GD supports particular image type
    908  *
    909  * @since 2.9.0
    910  *
    911  * @param string $mime_type
    912  * @return bool
    913  */
    914 function gd_edit_image_support($mime_type) {
    915     if ( function_exists('imagetypes') ) {
    916         switch( $mime_type ) {
    917             case 'image/jpeg':
    918                 return (imagetypes() & IMG_JPG) != 0;
    919             case 'image/png':
    920                 return (imagetypes() & IMG_PNG) != 0;
    921             case 'image/gif':
    922                 return (imagetypes() & IMG_GIF) != 0;
    923         }
    924     } else {
    925         switch( $mime_type ) {
    926             case 'image/jpeg':
    927                 return function_exists('imagecreatefromjpeg');
    928             case 'image/png':
    929                 return function_exists('imagecreatefrompng');
    930             case 'image/gif':
    931                 return function_exists('imagecreatefromgif');
    932         }
    933     }
    934     return false;
    935 }
    936 
    937 /**
    938907 * Create new GD image resource with transparency support
    939908 * @TODO: Deprecate if possible.
     
    11691138    $bytes   = apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes );
    11701139    return $bytes;
     1140}
     1141
     1142/**
     1143 * Returns a WP_Image_Editor instance and loads file into it.
     1144 *
     1145 * @since 3.5.0
     1146 * @access public
     1147 *
     1148 * @param string $path Path to file to load
     1149 * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} }
     1150 * @return WP_Image_Editor|WP_Error
     1151 */
     1152function wp_get_image_editor( $path, $args = array() ) {
     1153    $args['path'] = $path;
     1154
     1155    if ( ! isset( $args['mime_type'] ) ) {
     1156        $file_info  = wp_check_filetype( $args['path'] );
     1157
     1158        // If $file_info['type'] is false, then we let the editor attempt to
     1159        // figure out the file type, rather than forcing a failure based on extension.
     1160        if ( isset( $file_info ) && $file_info['type'] )
     1161            $args['mime_type'] = $file_info['type'];
     1162    }
     1163
     1164    $implementation = apply_filters( 'wp_image_editor_class', _wp_image_editor_choose( $args ) );
     1165
     1166    if ( $implementation ) {
     1167        $editor = new $implementation( $path );
     1168        $loaded = $editor->load();
     1169
     1170        if ( is_wp_error( $loaded ) )
     1171            return $loaded;
     1172
     1173        return $editor;
     1174    }
     1175
     1176    return new WP_Error( 'image_no_editor', __('No editor could be selected.') );
     1177}
     1178
     1179/**
     1180 * Tests whether there is an editor that supports a given mime type or methods.
     1181 *
     1182 * @since 3.5.0
     1183 * @access public
     1184 *
     1185 * @param string|array $args Array of requirements.  Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} }
     1186 * @return boolean true if an eligible editor is found; false otherwise
     1187 */
     1188function wp_image_editor_supports( $args = array() ) {
     1189    return (bool) _wp_image_editor_choose( $args );
     1190}
     1191
     1192/**
     1193 * Tests which editors are capable of supporting the request.
     1194 *
     1195 * @since 3.5.0
     1196 * @access private
     1197 *
     1198 * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} }
     1199 * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request.
     1200 */
     1201function _wp_image_editor_choose( $args = array() ) {
     1202    require_once ABSPATH . WPINC . '/class-wp-image-editor.php';
     1203    require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
     1204    require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
     1205
     1206    $implementations = apply_filters( 'wp_image_editors',
     1207        array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
     1208
     1209    foreach ( $implementations as $implementation ) {
     1210        if ( ! call_user_func( array( $implementation, 'test' ), $args ) )
     1211            continue;
     1212
     1213        if ( isset( $args['mime_type'] ) &&
     1214            ! call_user_func(
     1215                array( $implementation, 'supports_mime_type' ),
     1216                $args['mime_type'] ) ) {
     1217            continue;
     1218        }
     1219
     1220        if ( isset( $args['methods'] ) &&
     1221             array_diff( $args['methods'], get_class_methods( $implementation ) ) ) {
     1222            continue;
     1223        }
     1224
     1225        return $implementation;
     1226    }
     1227
     1228    return false;
    11711229}
    11721230
  • trunk/wp-settings.php

    r22434 r22817  
    144144require( ABSPATH . WPINC . '/admin-bar.php' );
    145145
    146 require( ABSPATH . WPINC . '/class-wp-image-editor.php' );
    147 require( ABSPATH . WPINC . '/class-wp-image-editor-gd.php' );
    148 require( ABSPATH . WPINC . '/class-wp-image-editor-imagick.php' );
    149 
    150146// Load multisite-specific files.
    151147if ( is_multisite() ) {
Note: See TracChangeset for help on using the changeset viewer.