diff --git a/wire/config.php b/wire/config.php
index 6f9b6741..05da4841 100644
--- a/wire/config.php
+++ b/wire/config.php
@@ -616,6 +616,40 @@ $config->fileContentTypes = array(
'mp3' => 'audio/mpeg',
);
+/**
+ * Named predefined image sizes and options
+ *
+ * Specify associative arrays of predefined image sizes indexed by name.
+ * Each item should have at least 'width' and 'height' indexes. But they can also have any
+ * other option accepted by the `Pageimage::size()` method `$options` argument.
+ *
+ * You can use your defined sizes by name in a Pageimage::size() call by specifying the
+ * size name rather than the `$width` argument, like this:
+ * ~~~~~~
+ * $image = $page->images->first();
+ * $landscape = $image->size('landscape');
+ * echo "
";
+ * ~~~~~~
+ * Feel free to completely overwrite the default $config->imageSizes in your /site/config.php
+ * file * as this particular setting is not used by the core.
+ *
+ * @var array
+ * @since 3.0.151
+ *
+ */
+$config->imageSizes = array(
+ // Example 1: Landscape (try this one if you want to test the feature)
+ 'landscape' => array('width' => 600, 'height' => 300),
+
+ // Example 2: Thumbnails in admin (260 height, proportional width)
+ // 'admin' => array('width' => 0, 'height' => 260),
+
+ // Example 3: Portrait, with additional options:
+ // 'portrait' => array('width' => 300, 'height' => 500, 'quality' => 80, 'suffix' => 'portrait'),
+
+ // Example 4: Square size cropping towards (preserving) top/center (north):
+ // 'squareNorth' => array('width' => 400, 'height' => 400, 'cropping' => 'north'),
+);
/**
* Image sizer options
@@ -1318,7 +1352,16 @@ $config->adminEmail = '';
* @var string
*
*/
-$config->fatalErrorHTML = "
{message}
{why}
";
+$config->fatalErrorHTML = "{message}
{why}
";
+
+/**
+ * HTTP code to send for fatal error (typically 500 or 503)
+ *
+ * @var int
+ * @since 3.0.151
+ *
+ */
+$config->fatalErrorCode = 500;
/**
* Settings for modal windows
diff --git a/wire/core/Config.php b/wire/core/Config.php
index 2116f161..a4a4e191 100644
--- a/wire/core/Config.php
+++ b/wire/core/Config.php
@@ -40,6 +40,7 @@
*
* @property bool $protectCSRF Enables CSRF (cross site request forgery) protection on all PW forms, recommended for security. #pw-group-HTTP-and-input
*
+ * @property array $imageSizes Predefined image sizes (and options) indexed by name. See /wire/config.php for example. (3.0.151+) #pw-group-images
* @property array $imageSizerOptions Options to set image sizing defaults. Please see the /wire/config.php file for all options and defaults. #pw-group-images
* @property array $webpOptions Options for webp images. Please see /wire/config.php for all options. #pw-group-images
*
@@ -135,6 +136,7 @@
* @property bool $logIP Include IP address in logs, when applicable? #pw-group-admin
* @property string $defaultAdminTheme Default admin theme: AdminThemeDefault or AdminThemeReno #pw-group-admin
* @property string $fatalErrorHTML HTML used for fatal error messages in HTTP mode. #pw-group-system
+ * @property int $fatalErrorCode HTTP code to send on fatal error (typically 500 or 503). #pw-group-system
* @property array $modals Settings for modal windows #pw-group-admin
* @property array $preloadCacheNames Cache names to preload at beginning of request #pw-group-system
* @property bool $allowExceptions Allow Exceptions to propagate? (default=false, specify true only if you implement your own exception handler) #pw-group-system
diff --git a/wire/core/Pageimage.php b/wire/core/Pageimage.php
index 4898648f..3b0e5989 100644
--- a/wire/core/Pageimage.php
+++ b/wire/core/Pageimage.php
@@ -24,7 +24,7 @@
* ~~~~~
* #pw-body
*
- * ProcessWire 3.x, Copyright 2018 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* https://processwire.com
*
* @property-read int $width Width of image, in pixels.
@@ -480,7 +480,11 @@ class Pageimage extends Pagefile {
} else {
$info = @getimagesize($this->filename);
}
- if($info) {
+ if((!$info || empty($info[0])) && !empty($this->sizeOptions['_width'])) {
+ // on fail, fallback to size options that were requested for the image (if available)
+ $imageInfo['width'] = $this->sizeOptions['_width'];
+ $imageInfo['height'] = $this->sizeOptions['_height'];
+ } else if($info) {
$imageInfo['width'] = $info[0];
$imageInfo['height'] = $info[1];
}
@@ -565,6 +569,9 @@ class Pageimage extends Pagefile {
*
* // Output thumbnail
* echo "
";
+ *
+ * // Create image of size predefined in $config->imageSizes (3.0.151+)
+ * $photo = $image->size('landscape');
* ~~~~~
*
* **About the $options argument**
@@ -625,8 +632,8 @@ class Pageimage extends Pagefile {
* #pw-group-common
* #pw-hooks
*
- * @param int $width Target width of new image
- * @param int $height Target height of new image
+ * @param int|string $width Target width of new image or (3.0.151+) specify prefined image size name
+ * @param int|array $height Target height of new image or (3.0.151+) options array if no height argument needed
* @param array|string|int $options Array of options to override default behavior:
* - Specify `array` of options as indicated in the section above.
* - Or you may specify type `string` containing "cropping" value.
@@ -636,8 +643,21 @@ class Pageimage extends Pagefile {
* If the specified dimensions/options are the same as the original, then the original will be returned.
*
*/
- public function size($width, $height, $options = array()) {
- if(!is_array($options)) $options = $this->sizeOptionsToArray($options);
+ public function size($width, $height = 0, $options = array()) {
+
+ if(is_array($height)) {
+ $options = $height;
+ $height = 0;
+ }
+
+ if(!is_array($options)) {
+ $options = $this->sizeOptionsToArray($options);
+ }
+
+ if(is_string($width) && $width && !ctype_digit($width)) {
+ // named image size
+ return $this->sizeName($width, $options);
+ }
if($this->wire('hooks')->isHooked('Pageimage::size()')) {
$result = $this->__call('size', array($width, $height, $options));
@@ -946,6 +966,31 @@ class Pageimage extends Pagefile {
return $this->size($width, $height, $options);
}
+ /**
+ * Return image of size indicated by predefined setting
+ *
+ * Settings for predefined sizes can be specified in `$config->imageSizes` array.
+ * Each named item in this array must contain at least 'width' and 'height, but can also
+ * contain any other option from the `Pageimage::size()` argument `$options`.
+ *
+ * @param string $name Image size name
+ * @param array $options Optionally add or override options defined for size.
+ * @return Pageimage
+ * @since 3.0.151
+ * @throws WireException If given a $name that is not present in $config->imageSizes
+ *
+ */
+ public function sizeName($name, array $options = array()) {
+ $sizes = $this->wire('config')->imageSizes;
+ if(!isset($sizes[$name])) throw new WireException("Unknown image size '$name' (not in \$config->imageSizes)");
+ $size = $sizes[$name];
+ $options = array_merge($size, $options);
+ unset($options['width'], $options['height']);
+ if(!isset($size['width'])) $size['width'] = 0;
+ if(!isset($size['height'])) $size['height'] = 0;
+ return $this->size((int) $size['width'], (int) $size['height'], $options);
+ }
+
/**
* Create a crop and return it as a new Pageimage.
*