1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-14 18:55:56 +02:00

Upgrade ImageSizer to provide a new getEngineInfo() method that enables you to get verbose information about all installed engines (such as supported source/target formats, and more) without having to supply a file to inspect.

This commit is contained in:
Ryan Cramer
2019-08-15 05:37:38 -04:00
parent 4a9a7fadb8
commit 429b98023b
6 changed files with 208 additions and 18 deletions

View File

@@ -11,7 +11,7 @@
*
* Other user contributions as noted.
*
* Copyright (C) 2016 by Horst Nogajski and Ryan Cramer
* Copyright (C) 2016-2019 by Horst Nogajski and Ryan Cramer
* This file licensed under Mozilla Public License v2.0 http://mozilla.org/MPL/2.0/
*
* @method bool resize($targetWidth, $targetHeight = 0)
@@ -115,15 +115,21 @@ class ImageSizer extends Wire {
self::$knownEngines = array();
$modules = $this->wire('modules');
$engines = $modules->find("className^=ImageSizerEngine");
$engines = $modules->findByPrefix('ImageSizerEngine');
$numEngines = count($engines);
foreach($engines as $module) {
$moduleName = $module->className();
foreach($engines as $moduleName) {
if(!$modules->isInstalled($moduleName)) continue;
if(count($engines) > 1) {
$configData = $modules->getModuleConfigData($moduleName);
if($numEngines > 1) {
$configData = $modules->getConfig($moduleName);
$priority = isset($configData['enginePriority']) ? (int) $configData['enginePriority'] : 0;
while(isset(self::$knownEngines[$priority])) $priority++;
// multiply by 10 to ensure two priority 1 engines don't get mixed up with a priority 2 engine
// for instance, two priority 1 engines become 10 and 11, rather than 1 and 2, as a priority 1
// engine incremented to 2 could otherwise be confused with a priority 2 engine
$priority *= 10;
while(isset(self::$knownEngines[$priority])) {
$priority++;
}
} else {
$priority = 0;
}
@@ -131,9 +137,61 @@ class ImageSizer extends Wire {
}
if(count(self::$knownEngines) > 1) ksort(self::$knownEngines);
self::$knownEngines[] = $this->defaultEngineName;
return self::$knownEngines;
}
/**
* Get array of information for all ImageSizer engines (or optionally a specific ImageSizer engine)
*
* Returns array of arrays indexed by engine name, each with the following:
*
* - `name` (string): engine name
* - `title` (string): engine title
* - `class` (string): PHP class name for engine
* - `summary` (string): Single sentence summary of the engine
* - `author` (string): Authr name (if available)
* - `moduleVersion` (string): Version of the module that powers this engine
* - `libraryVersion` (string): Version of the library that powers this engine
* - `sources` (array): Supported formats for source images it reads (i.e. JPG, JPEG, PNG, PNG24, GIF, GIF87, etc.)
* - `targets` (array): Supported formats for target images it creates (i.e. JPG, PNG, PNG24, WEBP, etc.)
* - `quality` (int): Current quality setting configured with the engine
* - `sharpening` (string): Current sharpening setting configured with the engine
* - `priority` (int): Engine priority (lower is higher priority)
* - `runOrder` (int): Order ImageSizer will try this engine in relative to others (lower runs first), derived from priority.
*
* @param string $name Specify engine name to get info just for that engine or omit to get info for all engines (default)
* @return array Array of arrays indexed by engine name, or if $name specified then just array of info for that engine.
* Returns empty array on error.
* @since 3.0.138
*
*/
public function getEngineInfo($name = '') {
$infos = array();
$engineNames = $name ? array($name) : $this->getEngines();
$prefix = 'ImageSizerEngine';
if($name && stripos($name, $prefix) === 0) {
$name = str_replace($prefix, '', $name);
}
foreach($engineNames as $priority => $engineName) {
$shortName = str_replace($prefix, '', $engineName);
if($name && $shortName !== $name) continue;
$engine = $this->getEngine($engineName);
if(!$engine) continue;
$info = $engine->getEngineInfo();
$info['runOrder'] = $priority;
$infos[$shortName] = $info;
}
// if one engine requested reduce array to just that engine
if($name) $infos = isset($infos[$name]) ? $infos[$name] : array();
return $infos;
}
/**
* Instantiate an ImageSizerEngine
@@ -161,20 +219,13 @@ class ImageSizer extends Wire {
$engine = null;
$bestFallbackEngine = null; // first engine that was supported but failed webp check
$engineNames = $this->getEngines();
$engineNames[] = $this->defaultEngineName;
// find first supported engine, according to knownEngines priority
foreach($engineNames as $engineName) {
if($this->forceEngineName && $engineName != $this->forceEngineName) continue;
if($engineName === $this->defaultEngineName) {
$engineClass = __NAMESPACE__ . "\\$engineName";
$e = $this->wire(new $engineClass());
} else {
$e = $this->wire('modules')->get($engineName);
}
$e = $this->getEngine($engineName);
if(!$e) continue;
/** @var ImageSizerEngine $e */
@@ -365,11 +416,24 @@ class ImageSizer extends Wire {
/**
* Get the current ImageSizerEngine
*
* @return ImageSizerEngine
* @param string $engineName Optionally specify a specific engine name to get a new instance of that engine
* When used, returned engine is in an unprepared state (no filename assigned, etc.). Since 3.0.138.
* @return ImageSizerEngine|null Returns ImageSizerEngine or null only if requested $engineName is not found.
* If no $engineName is specified this method may return an existing instance from a previous call.
* @throws WireException
*
*/
public function getEngine() {
public function getEngine($engineName = '') {
if($engineName) {
if($engineName === $this->defaultEngineName) {
$engineClass = __NAMESPACE__ . "\\$engineName";
$engine = $this->wire(new $engineClass());
} else {
$engine = $this->wire('modules')->get($engineName);
}
return $engine;
}
if($this->engine) return $this->engine;

View File

@@ -486,6 +486,64 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
return $this->validSourceImageFormats();
}
/**
* Get an array of image file formats this ImageSizerModule can use as source or target
*
* Unless using the $type argument, returned array contains 'source' and 'target' indexes,
* each an array of image file types/extensions in uppercase.
*
* @param string $type Specify 'source' or 'target' to get just those formats, or omit to get all.
* @return array
* @since 3.0.138
*
*/
public function getSupportedFormats($type = '') {
$a = array(
'source' => $this->validSourceImageFormats(),
'target' => $this->validTargetImageFormats()
);
return $type && isset($a[$type]) ? $a[$type] : $a;
}
/**
* Get array of information about this engine
*
* @return array
* @since 3.0.138
*
*/
public function getEngineInfo() {
$formats = $this->getSupportedFormats();
$moduleName = $this->className();
$className = $this->className(true);
if(is_callable("$className::getModuleInfo")) {
$moduleInfo = $className::getModuleInfo();
} else {
$moduleInfo = $this->wire('modules')->getModuleInfoVerbose($className);
}
if(!is_array($moduleInfo)) $moduleInfo = array();
$info = array(
'name' => str_replace('ImageSizerEngine', '', $moduleName),
'title' => isset($moduleInfo['title']) ? $moduleInfo['title'] : '',
'class' => $moduleName,
'summary' => isset($moduleInfo['summary']) ? $moduleInfo['summary'] : '',
'author' => isset($moduleInfo['author']) ? $moduleInfo['author'] : '',
'moduleVersion' => isset($moduleInfo['version']) ? $moduleInfo['version'] : '',
'libraryVersion' => $this->getLibraryVersion(),
'priority' => $this->enginePriority,
'sources' => $formats['source'],
'targets' => $formats['target'],
'quality' => $this->quality,
'sharpening' => $this->sharpening,
);
return $info;
}
/*************************************************************************************************
* COMMON IMPLEMENTATION METHODS
*
@@ -1983,6 +2041,17 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
return $this->moduleConfigData;
}
/**
* Get library version string
*
* @return string Returns version string or blank string if not applicable/available
* @since 3.0.138
*
*/
public function getLibraryVersion() {
return '';
}
/**
* Module configuration
*

View File

@@ -18,6 +18,15 @@
*/
class ImageSizerEngineGD extends ImageSizerEngine {
public static function getModuleInfo() {
return array(
'title' => 'GD Image Sizer',
'version' => 1,
'summary' => "Uses PHPs built-in GD library to resize images.",
'author' => 'Horst Nogajski',
);
}
/**
* @var string
*
@@ -54,6 +63,30 @@ class ImageSizerEngineGD extends ImageSizerEngine {
return array('JPG', 'JPEG', 'PNG', 'GIF');
}
/**
* Get an array of image file extensions this ImageSizerModule can create
*
* @return array of uppercase file extensions, i.e. ['PNG', 'JPG']
*
*/
protected function validTargetImageFormats() {
$formats = $this->validSourceImageFormats();
if($this->supported('webp')) $formats[] = 'WEBP';
return $formats;
}
/**
* Get library version string
*
* @return string Returns version string or blank string if not applicable/available
* @since 3.0.138
*
*/
public function getLibraryVersion() {
$gd = gd_info();
return isset($gd['GD Version']) ? $gd['GD Version'] : '';
}
/**
* Return whether or not GD can proceed - Is the current image(sub)format supported?
*

View File

@@ -73,7 +73,7 @@ class Pageimages extends Pagefiles {
* Does this field have the given file name? If so, return it, if not return null.
*
* @param string $name Basename is assumed
* @return null|Pagefile Returns Pagefile object if found, null if not
* @return null|Pagefile|Pageimage Returns Pagefile object if found, null if not
*
*/
public function getFile($name) {

View File

@@ -61,6 +61,18 @@ class ImageSizerEngineAnimatedGif extends ImageSizerEngine {
protected function validTargetImageFormats() {
return $this->validSourceImageFormats();
}
/**
* Get library version string
*
* @return string Returns version string or blank string if not applicable/available
* @since 3.0.138
*
*/
public function getLibraryVersion() {
$gd = gd_info();
return isset($gd['GD Version']) ? $gd['GD Version'] : '';
}
/**
* Is GD supported?

View File

@@ -135,6 +135,18 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
if($this->supportsFormat('WEBP')) $formats[] = 'WEBP';
return $formats;
}
/**
* Get library version string
*
* @return string Returns version string or blank string if not applicable/available
* @since 3.0.138
*
*/
public function getLibraryVersion() {
$a = \Imagick::getVersion();
return "$a[versionString] n=$a[versionNumber]";
}
/**
* Is the given image format supported by this IMagick for source and target? (RJC)