158 lines
4.2 KiB
PHP
158 lines
4.2 KiB
PHP
<?php
|
|
defined( 'WPINC' ) OR exit;
|
|
|
|
class DG_GhostscriptThumber extends DG_AbstractThumber {
|
|
|
|
/**
|
|
* Initialize the thumber class for use in thumbnail generation.
|
|
*/
|
|
public static function init() {
|
|
$options = DG_Thumber::getOptions();
|
|
$active = $options['active'];
|
|
if ( $active['gs'] && self::isGhostscriptAvailable() ) {
|
|
parent::init();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get thumbnail for document with given ID using Ghostscript. Imagick could
|
|
* also handle this, but is *much* slower.
|
|
*
|
|
* @param int $ID The attachment ID to retrieve thumbnail from.
|
|
* @param int $pg The page number to make thumbnail of -- index starts at 1.
|
|
*
|
|
* @return bool|string False on failure, URL to thumb on success.
|
|
*/
|
|
public function getThumbnail($ID, $pg = 1) {
|
|
static $gs = null;
|
|
|
|
if ( is_null( $gs ) ) {
|
|
$options = DG_Thumber::getOptions();
|
|
$gs = $options['gs'];
|
|
|
|
if ( false !== $gs ) {
|
|
$gs = escapeshellarg( $gs ) . ' -sDEVICE=png16m -dFirstPage=%1$d'
|
|
. ' -dLastPage=%1$d -dBATCH -dNOPAUSE -dPDFFitPage -sOutputFile=%2$s %3$s 2>&1';
|
|
}
|
|
}
|
|
|
|
if ( false === $gs ) {
|
|
return false;
|
|
}
|
|
|
|
$doc_path = get_attached_file( $ID );
|
|
$temp_path = DG_Util::getTempFile();
|
|
|
|
$old_locale = setlocale( LC_CTYPE, 0 );
|
|
setlocale( LC_CTYPE, 'en_US.UTF-8' );
|
|
$cmd = sprintf( $gs, $pg, escapeshellarg( $temp_path ), escapeshellarg( $doc_path ) );
|
|
if ( false !== $old_locale ) {
|
|
setlocale( LC_CTYPE, $old_locale );
|
|
}
|
|
|
|
DG_Logger::writeLog( DG_LogLevel::Detail, 'Executing: ' . $cmd );
|
|
exec( $cmd, $out, $ret );
|
|
|
|
if ( $ret != 0 ) {
|
|
DG_Logger::writeLog( DG_LogLevel::Error, __( 'Ghostscript failed: ', 'document-gallery' ) . print_r( $out ) );
|
|
@unlink( $temp_path );
|
|
|
|
return false;
|
|
}
|
|
|
|
return $temp_path;
|
|
}
|
|
/**
|
|
* @return string[] The extensions supported by this thumber.
|
|
*/
|
|
protected function getThumberExtensions() {
|
|
return array( 'pdf', 'ps', 'eps' );
|
|
}
|
|
|
|
/**
|
|
* Dynamically determines whether we may call gs through exec().
|
|
*
|
|
* NOTE: This does not check the options for gs path. Don't use in
|
|
* thumbnail generation as it's slow and not configurable.
|
|
*
|
|
* @return bool|string If available, returns exe path. False otherwise.
|
|
*/
|
|
public static function getGhostscriptExecutable() {
|
|
static $executable = null;
|
|
|
|
if ( is_null( $executable ) ) {
|
|
// we must be able to exec()
|
|
$executable = self::isExecAvailable();
|
|
if ( ! $executable ) {
|
|
return $executable;
|
|
}
|
|
|
|
// find on Windows system
|
|
if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) {
|
|
// look for environment variable
|
|
$executable = getenv( 'GSC' );
|
|
if ( $executable ) {
|
|
return $executable;
|
|
}
|
|
|
|
// hope GS in the path
|
|
$executable = exec( 'where gswin*c.exe' );
|
|
if ( ! empty( $executable ) ) {
|
|
return $executable;
|
|
}
|
|
|
|
// look directly in filesystem
|
|
// 64- or 32-bit binary
|
|
$executable = exec( 'dir /o:n/s/b "C:\Program Files\gs\*gswin*c.exe"' );
|
|
if ( ! empty( $executable ) ) {
|
|
return $executable;
|
|
}
|
|
|
|
// 32-bit binary on 64-bit OS
|
|
$executable = exec( 'dir /o:n/s/b "C:\Program Files (x86)\gs\*gswin32c.exe"' );
|
|
$executable = empty( $executable ) ? false : $executable;
|
|
|
|
return $executable;
|
|
}
|
|
|
|
// handle Linux systems
|
|
$executable = exec( 'which gs' );
|
|
if ( ! empty( $executable ) ) {
|
|
return $executable;
|
|
}
|
|
|
|
// GoDaddy and others aren't setup in such a way that
|
|
// the above works so we need to fallback to a direct
|
|
// filesystem check in most common location
|
|
exec( 'test -e /usr/bin/gs', $dummy, $ret );
|
|
$executable = ( $ret === 0 ) ? '/usr/bin/gs' : false;
|
|
|
|
return $executable;
|
|
}
|
|
|
|
return $executable;
|
|
}
|
|
|
|
/**
|
|
* @return bool Whether we can use the GS executable.
|
|
*/
|
|
public static function isGhostscriptAvailable() {
|
|
static $ret = null;
|
|
|
|
if ( is_null( $ret ) ) {
|
|
$options = DG_Thumber::getOptions();
|
|
$ret = $options['gs'] && self::isExecAvailable();
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @return int An integer from 0 to 100. Higher priorities will be attempted before lower priority thumbers.
|
|
*/
|
|
public function getPriority() {
|
|
return 75;
|
|
}
|
|
}
|
|
|
|
DG_GhostscriptThumber::init(); |