188 lines
5.3 KiB
PHP
188 lines
5.3 KiB
PHP
<?php
|
|
defined( 'WPINC' ) OR exit;
|
|
|
|
include_once DG_WPINC_PATH . 'class-wp-image-editor.php';
|
|
include_once DG_WPINC_PATH . 'class-wp-image-editor-imagick.php';
|
|
|
|
/**
|
|
* Extends WP_Image_Editor_Imagick to support specifying which
|
|
* page to open for an Imagick file.
|
|
*
|
|
* @author drossiter
|
|
*/
|
|
class DG_Image_Editor_Imagick extends WP_Image_Editor_Imagick {
|
|
/**
|
|
* @var int The 0-indexed pg number
|
|
*/
|
|
private $pg;
|
|
|
|
/**
|
|
* @param string $file
|
|
* @param int $pg The 0-indexed pg number to edit.
|
|
*/
|
|
public function __construct( $file, $pg = null ) {
|
|
parent::__construct( $file );
|
|
$this->pg = $pg;
|
|
}
|
|
|
|
/**
|
|
* @return string[]|bool The formats supported by Imagick, or false
|
|
*/
|
|
public static function query_formats() {
|
|
try {
|
|
return @Imagick::queryFormats();
|
|
} catch ( Exception $ex ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TODO: Can be removed once WP < 4.7 is no longer supported
|
|
*
|
|
* Checks to see if current environment supports Imagick.
|
|
*
|
|
* We require Imagick 2.2.0 or greater, based on whether the queryFormats()
|
|
* method can be called statically.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @static
|
|
* @access public
|
|
*
|
|
* @param array $args
|
|
* @return bool
|
|
*/
|
|
public static function test( $args = array() ) {
|
|
global $wp_version;
|
|
if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
|
|
return parent::test( $args );
|
|
} else {
|
|
return parent::test( $args ) && in_array( 'readimage', array_map( 'strtolower', get_class_methods( 'Imagick' ) ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads image from $this->file into new Imagick Object.
|
|
*
|
|
* @since 3.5.0
|
|
* @access protected
|
|
*
|
|
* @return true|WP_Error True if loaded; WP_Error on failure.
|
|
*/
|
|
public function load() {
|
|
if ( $this->image instanceof Imagick ) {
|
|
return true;
|
|
}
|
|
|
|
global $wp_version;
|
|
if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
|
|
$ret = parent::load();
|
|
} else {
|
|
// TODO: Can be removed once WP < 4.7 is no longer supported
|
|
|
|
if ( ! is_file( $this->file ) && ! preg_match( '|^https?://|', $this->file ) )
|
|
$ret = new WP_Error( 'error_loading_image', __('File doesn’t exist?'), $this->file );
|
|
|
|
/*
|
|
* Even though Imagick uses less PHP memory than GD, set higher limit
|
|
* for users that have low PHP.ini limits.
|
|
*/
|
|
if ( version_compare( $wp_version, '4.6.0', '>=' ) ) {
|
|
wp_raise_memory_limit( 'image' );
|
|
} else {
|
|
// TODO: Can be removed once WP < 4.6 is no longer supported
|
|
@ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
|
}
|
|
|
|
try {
|
|
$this->image = new Imagick();
|
|
$file_parts = pathinfo( $this->file );
|
|
$filename = $this->file;
|
|
|
|
if ( 'pdf' == strtolower( $file_parts['extension'] ) ) {
|
|
$filename = $this->pdf_setup();
|
|
}
|
|
|
|
// Reading image after Imagick instantiation because `setResolution`
|
|
// only applies correctly before the image is read.
|
|
$this->image->readImage( $filename );
|
|
|
|
if ( ! $this->image->valid() ) {
|
|
$ret = new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file );
|
|
} else {
|
|
$this->mime_type = $this->get_mime_type( $this->image->getImageFormat() );
|
|
}
|
|
}
|
|
catch ( Exception $e ) {
|
|
$ret = new WP_Error( 'invalid_image', $e->getMessage(), $this->file );
|
|
}
|
|
|
|
if ( ! isset( $ret ) ) {
|
|
$updated_size = $this->update_size();
|
|
if ( is_wp_error( $updated_size ) ) {
|
|
$ret = $updated_size;
|
|
} else {
|
|
$ret = $this->set_quality();
|
|
}
|
|
}
|
|
}
|
|
|
|
// set correct page number
|
|
if ( ! is_null( $this->pg ) && ! is_wp_error( $ret )
|
|
&& is_callable( array( $this->image, 'setIteratorIndex' ) ) ) {
|
|
$err = __( 'Failed to set Imagick page number', 'document-gallery' );
|
|
|
|
// setIteratorIndex() should return false on failure, but I've found
|
|
// reports of it throwing an error so handling both cases.
|
|
// NOTE: I've also seen it fail and return true, so we may not
|
|
// log anything on failure...
|
|
try {
|
|
if ( ! $this->image->setIteratorIndex( $this->pg ) ) {
|
|
DG_Logger::writeLog( DG_LogLevel::Error, $err . '.' );
|
|
}
|
|
} catch ( Exception $e ) {
|
|
DG_Logger::writeLog( DG_LogLevel::Error, $err . ': ' . $e->getMessage() );
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Sets up Imagick for PDF processing.
|
|
* Increases rendering DPI and only loads first page.
|
|
*
|
|
* @since 4.7.0
|
|
* @access protected
|
|
*
|
|
* @return string|WP_Error File to load or WP_Error on failure.
|
|
*/
|
|
protected function pdf_setup() {
|
|
$page = !is_null($this->pg) ? "[{$this->pg}]" : '[0]';
|
|
|
|
global $wp_version;
|
|
if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
|
|
$ret = rtrim( parent::pdf_setup(), '[0]' ) . $page;
|
|
} else {
|
|
// TODO: Can be removed once WP < 4.7 is no longer supported
|
|
|
|
try {
|
|
// By default, PDFs are rendered in a very low resolution.
|
|
// We want the thumbnail to be readable, so increase the rendering DPI.
|
|
$this->image->setResolution( 128, 128 );
|
|
|
|
// Only load the first page.
|
|
$ret = $this->file . $page;
|
|
}
|
|
catch ( Exception $e ) {
|
|
$ret = new WP_Error( 'pdf_setup_failed', $e->getMessage(), $this->file );
|
|
}
|
|
}
|
|
|
|
if ( is_wp_error( $ret ) ) {
|
|
DG_Logger::writeLog( DG_LogLevel::Error, $ret->get_error_code() . ': ' . $ret->get_error_message() );
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
} |