247 lines
8.1 KiB
PHP
247 lines
8.1 KiB
PHP
<?php namespace ProcessWire;
|
||
|
||
/**
|
||
* ProcessWire Pageimages
|
||
*
|
||
* #pw-summary Pageimages are a type of WireArray containing Pageimage objects. They represent the value of multi-image field in ProcessWire.
|
||
*
|
||
* #pw-body =
|
||
* Most of the methods you are likely to use are inherited from `Pagefiles` and `WireArray` so be sure to take a look at those as well.
|
||
* Pageimages is dedicated to containing `Pageimage` objects.
|
||
*
|
||
* ~~~~~
|
||
* // Example of outputting a thumbnail gallery of Pageimage objects
|
||
* foreach($page->images as $image) {
|
||
* // $page->images is a Pageimages object
|
||
* // $image and $thumb are both Pageimage objects
|
||
* $thumb = $image->size(200, 200);
|
||
* echo "<a href='$image->url'>";
|
||
* echo "<img src='$thumb->url' alt='$image->description' />";
|
||
* echo "</a>";
|
||
* }
|
||
* ~~~~~
|
||
* #pw-body
|
||
*
|
||
* Typically a Pageimages object will be associated with a specific field attached to a Page.
|
||
* There may be multiple instances of Pageimages attached to a given Page (depending on what fields are in it's fieldgroup).
|
||
*
|
||
* ProcessWire 3.x, Copyright 2019 by Ryan Cramer
|
||
* https://processwire.com
|
||
*
|
||
* @method string render($markup = '', $options = array())
|
||
*
|
||
*/
|
||
|
||
class Pageimages extends Pagefiles {
|
||
|
||
/**
|
||
* Per the WireArray interface, items must be of type Pagefile
|
||
*
|
||
* #pw-internal
|
||
*
|
||
* @param mixed $item
|
||
* @return bool
|
||
*
|
||
*/
|
||
public function isValidItem($item) {
|
||
return $item instanceof Pageimage;
|
||
}
|
||
|
||
/**
|
||
* Add a new Pageimage item, or create one from given filename and add it.
|
||
*
|
||
* @param Pageimage|string $item If item is a string (filename) then the Pageimage instance will be created automatically.
|
||
* @return Pageimages|Pagefiles
|
||
*
|
||
*/
|
||
public function add($item) {
|
||
if(is_string($item)) $item = $this->wire(new Pageimage($this, $item));
|
||
return parent::add($item);
|
||
}
|
||
|
||
/**
|
||
* Per the WireArray interface, return a blank Pageimage
|
||
*
|
||
* #pw-internal
|
||
*
|
||
* @return Pageimage
|
||
*
|
||
*/
|
||
public function makeBlankItem() {
|
||
return $this->wire(new Pageimage($this, ''));
|
||
}
|
||
|
||
/**
|
||
* 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|Pageimage Returns Pagefile object if found, null if not
|
||
*
|
||
*/
|
||
public function getFile($name) {
|
||
|
||
$hasFile = parent::getFile($name);
|
||
if($hasFile) return $hasFile;
|
||
|
||
// populate $base with $name sans ImageSizer info and extension
|
||
$name = basename($name);
|
||
$pos = strpos($name, '.');
|
||
$base = ($pos ? substr($name, 0, $pos) : null);
|
||
|
||
foreach($this as $pagefile) {
|
||
/** @var Pageimage $pagefile */
|
||
if($base !== null && strpos($pagefile->basename, $base) !== 0) continue;
|
||
// they start the same, is it a variation?
|
||
if(!$pagefile->isVariation($name)) continue;
|
||
// if we are here we found a variation
|
||
$hasFile = $pagefile;
|
||
break;
|
||
}
|
||
|
||
return $hasFile;
|
||
}
|
||
|
||
/**
|
||
* Get an array of all image variations on this field indexed by original file name.
|
||
*
|
||
* More information on any variation filename can be retrieved from `Pageimage::isVariation()`.
|
||
*
|
||
* ~~~~~
|
||
* $variations = $page->images->getAllVariations();
|
||
* print_r($variations);
|
||
* // Example output:
|
||
* // array(
|
||
* // 'foo.jpg' => array(
|
||
* // 'foo.100x100.jpg',
|
||
* // 'foo.200x200.jpg'
|
||
* // ),
|
||
* // 'bar.jpg' => array(
|
||
* // 'bar.300x300.jpg'
|
||
* // )
|
||
* // );
|
||
* ~~~~~
|
||
*
|
||
* @return array Array indexed by file name, each containing array of variation file names
|
||
* @see Pageimage::isVariation()
|
||
*
|
||
*/
|
||
public function getAllVariations() {
|
||
|
||
$variations = array();
|
||
$extensions = array();
|
||
$basenames = array();
|
||
|
||
foreach($this as $pageimage) {
|
||
/** @var Pageimage $pageimage */
|
||
$name = $pageimage->basename;
|
||
$ext = $pageimage->ext;
|
||
$extensions[$name] = $ext;
|
||
$basenames[$name] = basename($name, ".$ext");
|
||
$variations[$name] = array();
|
||
}
|
||
|
||
foreach(new \DirectoryIterator($this->path()) as $file) {
|
||
|
||
if($file->isDir() || $file->isDot()) continue;
|
||
|
||
$_ext = $file->getExtension();
|
||
$_name = $file->getBasename();
|
||
$_base = basename($_name, ".$_ext");
|
||
|
||
foreach($variations as $name => $unused) {
|
||
|
||
// if filenames match then it's an original, not a variation
|
||
if($name === $_name) continue;
|
||
|
||
// if files don't share same extension, skip
|
||
$ext = $extensions[$name];
|
||
if($ext != $_ext) continue;
|
||
|
||
// if files don't start the same, it's not a variation
|
||
$base = $basenames[$name];
|
||
if(strpos($_base, $base) !== 0) continue;
|
||
|
||
// if the part up to the first period isn't the same, then it's not a variation
|
||
$test1 = substr($name, 0, strpos($name, '.'));
|
||
$test2 = substr($_name, 0, strpos($_name, '.'));
|
||
if($test1 !== $test2) continue;
|
||
|
||
// if we reach this point, we've found a variation
|
||
$variations[$name][] = $_name;
|
||
}
|
||
}
|
||
|
||
return $variations;
|
||
}
|
||
|
||
/**
|
||
* Render markup for all images here (optionally using a provided markup template string and/or image size options)
|
||
*
|
||
* Given template string can contain any of the placeholders, which will be replaced:
|
||
* - `{url}` or `{src}` Image URL (typically used for src attribute)
|
||
* - `{httpUrl}` File URL with scheme and hostname (alternate for src attribute)
|
||
* - `{URL}` Same as url but with cache busting query string
|
||
* - `{HTTPURL}` Same as httpUrl but with cache busting query string
|
||
* - `{description}` or `{alt}` Image description (typically used in alt attribute)
|
||
* - `{tags}` File tags (might be useful in class attribute)
|
||
* - `{width}` Width of image
|
||
* - `{height}` Height of image
|
||
* - `{hidpiWidth}` HiDPI width of image
|
||
* - `{hidpiHeight}` HiDPI height of image
|
||
* - `{ext}` File extension
|
||
* - `{original.name}` Replace “name” with any of the properties above to refer to original/full-size image.
|
||
* If there is no original image then these just refer back to the current image.
|
||
*
|
||
* ~~~~~
|
||
* // default output
|
||
* echo $page->images->render();
|
||
*
|
||
* // custom output
|
||
* echo $page->images->render("<img class='pw-image' src='{url}' alt='{alt}'>");
|
||
*
|
||
* // custom output with options
|
||
* echo $page->images->render("<img src='{url}' alt='{alt}'>", [ 'width' => 300 ]);
|
||
*
|
||
* // options can go in first argument if you prefer
|
||
* echo $page->images->render([ 'width' => 300, 'height' => 200 ]);
|
||
*
|
||
* // if only width/height are needed, they can also be specified as a string (1st or 2nd arg)
|
||
* echo $page->images->render('300x200');
|
||
*
|
||
* // custom output with link to original/full-size and square crop of 300x300 for thumbnails
|
||
* echo "<ul>" . $page->images->render([
|
||
* 'markup' => "<li><a href='{original.url}'><img src='{url}' alt='{alt}'></a></li>",
|
||
* 'width' => 300,
|
||
* 'height' => 300
|
||
* ]) . "</ul>";
|
||
* ~~~~~
|
||
*
|
||
* @param string|array $markup Markup template string or optional $options array if you do not want the template string here.
|
||
* @param array|string $options Optionally resize image with these options sent to size() method:
|
||
* - `width` (int): Target width or 0 for current image size (or proportional if height specified).
|
||
* - `height` (int): Target height or 0 for current image size (or proportional if width specified).
|
||
* - `markup` (string): Markup template string (same as $markup argument), or omit for default (same as $markup argument).
|
||
* - `link` (bool): Link image to original size? Though you may prefer to do this with your own $markup (see examples). (default=false)
|
||
* - `limit` (int): Render no more than this many images (default=0, no limit).
|
||
* - Plus any option available to the $options argument on the `Pageimage::size()` method.
|
||
* - If you only need width and/or height, you can specify a width x height string, i.e. 123x456 (use 0 for proportional).
|
||
* @return string
|
||
* @since 3.0.126
|
||
*
|
||
*/
|
||
public function ___render($markup = '', $options = array()) {
|
||
$out = '';
|
||
$limit = 0;
|
||
$n = 0;
|
||
if(isset($options['limit'])) {
|
||
$limit = (int) $options['limit'];
|
||
unset($options['limit']);
|
||
}
|
||
foreach($this as $image) {
|
||
/** @var Pageimage $image */
|
||
$out .= $image->render($markup, $options);
|
||
if($limit > 0 && ++$n >= $limit) break;
|
||
}
|
||
return $out;
|
||
}
|
||
}
|