Last active
August 29, 2015 14:13
-
-
Save Daniel-KM/c8534e60e9d839442ea9 to your computer and use it in GitHub Desktop.
Hack to use Omeka on some shared hosts (needed with Omeka < 2.3), as OVH (replace application/libraries/Omeka/File/Derivative/Strategy/ExternalImageMagick.php)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Adaptation pour que le serveur partagé d'OVH puisse créer les fichiers dérivés. | |
* | |
* @see application/libraries/Omeka/File/Derivative/Strategy/ExternalImageMagick.php | |
* | |
* @copyright Copyright 2007-2014 Roy Rosenzweig Center for History and New Media | |
* @license http://www.gnu.org/licenses/gpl-3.0.txt GNU GPLv3 | |
*/ | |
/** | |
* Strategy for making derivatives with ImageMagick on the command line. | |
* | |
* @package Omeka\File\Derivative\Strategy | |
*/ | |
class ExternalImageMagick | |
extends Omeka_File_Derivative_AbstractStrategy | |
{ | |
const IMAGEMAGICK_CONVERT_COMMAND = 'convert'; | |
private $_convertPath; | |
/** | |
* Generate a derivative image from an existing file stored in Omeka. | |
* | |
* This image will be generated based on a constraint given in pixels. For | |
* example, if the constraint is 500, the resulting image file will be scaled | |
* so that the largest side is 500px. If the image is less than 500px on both | |
* sides, the image will not be resized. | |
* | |
* Derivative images will only be generated for files with mime types | |
* that pass any configured blacklist and/or whitelist and can be processed | |
* by the convert binary. | |
* | |
* @throws Omeka_File_Derivative_Exception | |
* @param string Command line arguments to the ImageMagick binary. | |
* It assumes these command line arguments are already escaped as shell arguments | |
*/ | |
public function createImage($sourcePath, $destPath, $type, $sizeConstraint, $mimeType) | |
{ | |
$convertPath = $this->_getConvertPath(); | |
$convertArgs = $this->_getConvertArgs($type, $sizeConstraint); | |
$page = (int) $this->getOption('page', 0); | |
$cmd = join(' ', array( | |
escapeshellcmd($convertPath), | |
escapeshellarg($sourcePath . '[' . $page . ']'), | |
$convertArgs, | |
escapeshellarg($destPath) | |
)); | |
self::executeCommand($cmd, $status, $output, $errors); | |
/* | |
// Modification pour OVH. | |
if (!empty($errors)) { | |
_log("Error output from ImageMagick:\n$errors", Zend_Log::WARN); | |
} | |
if ($status) { | |
_log("ImageMagick failed with status code $status.", Zend_Log::ERR); | |
return false; | |
} | |
*/ | |
if (!empty($errors)) { | |
$msg = "Error output from ImageMagick:\n$errors"; | |
_log($msg, Zend_Log::WARN); | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Get the full path to the ImageMagick 'convert' command. | |
* | |
* @throws Omeka_File_Derivative_Exception When the path is not a valid directory. | |
* @return string | |
*/ | |
protected function _getConvertPath() | |
{ | |
// Assert that this is both a valid path and a directory (cannot be a | |
// script). | |
if (!empty($this->_convertPath)) { | |
return $this->_convertPath; | |
} | |
// Adaptation pour OVH. | |
$this->_convertPath = $this->getOption('convert_path'); | |
// if ($path && ($pathClean = realpath($path)) && is_dir($pathClean)) { | |
// TODO Add a check. | |
if ($this->_convertPath) { | |
// $pathClean = rtrim($pathClean, DIRECTORY_SEPARATOR); | |
// $this->_convertPath = $pathClean . DIRECTORY_SEPARATOR . self::IMAGEMAGICK_CONVERT_COMMAND; | |
return $this->_convertPath; | |
} else { | |
throw new Omeka_File_Derivative_Exception('ImageMagick is not properly configured: invalid directory given for the ImageMagick command!'); | |
} | |
} | |
/** | |
* Get the ImageMagick command line for resizing to the given constraints. | |
* | |
* @param string $type Type of derivative being made. | |
* @param int $constraint Maximum side length in pixels. | |
* @return string | |
*/ | |
protected function _getConvertArgs($type, $constraint) | |
{ | |
$version = $this->getOption('version', '0'); | |
if ($type != 'square_thumbnail') { | |
return '-background white -flatten -thumbnail ' . escapeshellarg("{$constraint}x{$constraint}>"); | |
} else { | |
$gravity = $this->getOption('gravity', 'Center'); | |
// Native square thumbnail resize requires at least version 6.3.8-3. | |
if (version_compare($version, '6.3.8-3', '>=')) { | |
$args = array( | |
'-background white', | |
'-flatten', | |
'-thumbnail ' . escapeshellarg("{$constraint}x{$constraint}^"), | |
'-gravity ' . escapeshellarg($gravity), | |
'-crop ' . escapeshellarg("{$constraint}x{$constraint}+0+0"), | |
'+repage' | |
); | |
} else { | |
$args = array( | |
'-thumbnail ' . escapeshellarg('x' . $constraint*2), | |
'-resize ' . escapeshellarg($constraint*2 . 'x<'), | |
'-resize 50%', | |
'-background white', | |
'-flatten', | |
'-gravity ' . escapeshellarg($gravity), | |
'-crop ' . escapeshellarg("{$constraint}x{$constraint}+0+0"), | |
'+repage' | |
); | |
} | |
return join (' ', $args); | |
} | |
} | |
/** | |
* Determine whether or not the path given to ImageMagick is valid. | |
* The convert binary must be within the directory and executable. | |
* | |
* @param string | |
* @return boolean | |
*/ | |
public static function isValidImageMagickPath($dirToIm) | |
{ | |
/* | |
if (!realpath($dirToIm) || !is_dir($dirToIm)) { | |
return false; | |
} | |
// Append the convert binary to the given path. | |
$imPath = rtrim($dirToIm, DIRECTORY_SEPARATOR); | |
$convertPath = $imPath . DIRECTORY_SEPARATOR . self::IMAGEMAGICK_CONVERT_COMMAND; | |
// Make sure the convert file is executable | |
if (!is_executable($convertPath)) { | |
return false; | |
} | |
// Attempt to run the ImageMagick binary with the version argument | |
// If you try to run it without any arguments, it returns an error code | |
$cmd = $convertPath . ' -version'; | |
self::executeCommand($cmd, $status, $output, $errors); | |
// A return value of 0 indicates the convert binary is working correctly. | |
return $status == 0; | |
// Adaptation pour OVH. | |
*/ | |
return true; | |
} | |
/** | |
* Retrieve the path to the directory containing ImageMagick's convert utility. | |
* | |
* Uses the 'which' command-line utility to detect the path to 'convert'. | |
* Note that this will only work if the convert utility is in PHP's PATH and | |
* thus can be located by 'which'. | |
* | |
* @return string The path to the directory if it can be found. Otherwise returns an empty string. | |
*/ | |
public static function getDefaultImageMagickDir() | |
{ | |
// Use the "which" command to auto-detect the path to ImageMagick | |
$cmd = 'which ' . self::IMAGEMAGICK_CONVERT_COMMAND; | |
try { | |
self::executeCommand($cmd, $status, $output, $errors); | |
/* | |
// Modification pour OVH. | |
return $status == 0 ? dirname($output) : ''; | |
*/ | |
return empty($errors) ? dirname($output[0]) : ''; | |
} catch (Omeka_File_Derivative_Exception $e) { | |
return ''; | |
} | |
} | |
public static function executeCommand($cmd, &$status, &$output, &$errors) | |
{ | |
/* | |
// Modification pour OVH. | |
// Using proc_open() instead of exec() solves a problem where exec('convert') | |
// fails with a "Permission Denied" error because the current working | |
// directory cannot be set properly via exec(). Note that exec() works | |
// fine when executing in the web environment but fails in CLI. | |
$descriptorSpec = array( | |
0 => array("pipe", "r"), //STDIN | |
1 => array("pipe", "w"), //STDOUT | |
2 => array("pipe", "w"), //STDERR | |
); | |
if ($proc = proc_open($cmd, $descriptorSpec, $pipes, getcwd())) { | |
$output = stream_get_contents($pipes[1]); | |
$errors = stream_get_contents($pipes[2]); | |
foreach ($pipes as $pipe) { | |
fclose($pipe); | |
} | |
$status = proc_close($proc); | |
} else { | |
throw new Omeka_File_Derivative_Exception("Failed to execute command: $cmd."); | |
} | |
*/ | |
exec($cmd, $output, $error); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment