diff --git a/wire/core/Pagefile.php b/wire/core/Pagefile.php index 45f59181..0de56bf3 100644 --- a/wire/core/Pagefile.php +++ b/wire/core/Pagefile.php @@ -28,10 +28,13 @@ * @property string $description Value of the file’s description field (string), if enabled. Note you can also set this property directly. * @property string $tags Value of the file’s tags field (string), if enabled. #pw-group-tags * @property string $ext File’s extension (i.e. last 3 or so characters) - * @property int $filesize File size (number of bytes). + * @property-read int $filesize File size (number of bytes). * @property int $modified Unix timestamp of when Pagefile (file, description or tags) was last modified. #pw-group-date-time - * @property int $mtime Unix timestamp of when file (only) was last modified. #pw-group-date-time + * @property-read string $modifiedStr Readable date/time string of when Pagefile was last modified. #pw-group-date-time + * @property-read int $mtime Unix timestamp of when file (only) was last modified. #pw-group-date-time + * @property-read string $mtimeStr Readable date/time string when file (only) was last modified. #pw-group-date-time * @property int $created Unix timestamp of when file was created. #pw-group-date-time + * @property-read string $createdStr Readable date/time string of when Pagefile was created #pw-group-date-time * @property string $filesizeStr File size as a formatted string, i.e. “123 Kb”. * @property Pagefiles $pagefiles The Pagefiles WireArray that contains this file. #pw-group-other * @property Page $page The Page object that this file is part of. #pw-group-other @@ -522,12 +525,21 @@ class Pagefile extends WireData { parent::set($key, $value); } break; + case 'modifiedStr': + case 'createdStr': + $value = parent::get(str_replace('Str', '', $key)); + $value = wireDate($this->wire('config')->dateFormat, $value); + break; case 'fileData': case 'filedata': $value = $this->filedata(); break; case 'mtime': + case 'mtimeStr': + case 'filemtime': + case 'filemtimeStr': $value = filemtime($this->filename()); + if(strpos($key, 'Str')) $value = wireDate($this->wire('config')->dateFormat, $value); break; } if(is_null($value)) return parent::get($key); @@ -1026,5 +1038,29 @@ class Pagefile extends WireData { public function isTemp($set = null) { return $this->pagefiles->isTemp($this, $set); } + + /** + * Debug info + * + * @return array + * + */ + public function __debugInfo() { + $filedata = $this->filedata(); + if(empty($filedata)) $filedata = null; + $info = array( + 'url' => $this->url(), + 'filename' => $this->filename(), + 'filesize' => $this->filesize(), + 'description' => $this->description, + 'tags' => $this->tags, + 'created' => $this->createdStr, + 'modified' => $this->modifiedStr, + 'filemtime' => $this->mtimeStr, + 'filedata' => $filedata, + ); + if(empty($info['filedata'])) unset($info['filedata']); + return $info; + } } diff --git a/wire/core/Pagefiles.php b/wire/core/Pagefiles.php index 2231cf41..97c375cb 100644 --- a/wire/core/Pagefiles.php +++ b/wire/core/Pagefiles.php @@ -38,7 +38,7 @@ * Typically a Pagefiles object will be associated with a specific field attached to a Page. * There may be multiple instances of Pagefiles attached to a given Page (depending on what fields are in it's fieldgroup). * - * ProcessWire 3.x, Copyright 2016 by Ryan Cramer + * ProcessWire 3.x, Copyright 2018 by Ryan Cramer * https://processwire.com * * @@ -905,5 +905,29 @@ class Pagefiles extends WireArray implements PageFieldValueInterface { return $this->formatted; } + /** + * Debug info + * + * @return array + * + */ + public function __debugInfo() { + + $info = array( + 'count' => $this->count(), + 'page' => $this->page ? $this->page->path() : '?', + 'field' => $this->field ? $this->field->name : '?', + 'url' => $this->url(), + 'path' => $this->path(), + 'items' => array(), + ); + + foreach($this as $key => $pagefile) { + /** @var Pagefile $pagefile */ + $info['items'][$key] = $pagefile->__debugInfo(); + } + + return $info; + } } diff --git a/wire/core/Pageimage.php b/wire/core/Pageimage.php index 056cbf6f..0cacc6de 100644 --- a/wire/core/Pageimage.php +++ b/wire/core/Pageimage.php @@ -36,10 +36,13 @@ * @property-read string $url * @property-read string $basename * @property-read string $filename - * @property-read array $focus Focus array contains 'top' (float), 'left' (float), 'zoom' (int), and 'default' (bool) properties. + * @property-read array $focus Focus array contains 'top' (float), 'left' (float), 'zoom' (int), and 'default' (bool) properties. + * @property-read string $focusStr Readable string containing focus information. * @property-read bool $hasFocus Does this image have custom focus settings? (i.e. $focus['default'] == true) + * @property-read array $suffix Array containing file suffix(es). + * @property-read string $suffixStr String of file suffix(es) separated by comma. * - * @method bool|array isVariation($basename, $allowSelf = false) + * @method bool|array isVariation($basename, $options = array()) * @method Pageimage crop($x, $y, $width, $height, $options = array()) * @method array rebuildVariations($mode = 0, array $suffix = array(), array $options = array()) * @method install($filename) @@ -201,7 +204,8 @@ class Pageimage extends Pagefile { * - SET: Specify both $top and $left arguments to set (values assumed to be percentages). * - SET: Specify array containing "top" and "left" indexes to set (percentages). * - SET: Specify array where index 0 is top and index 1 is left (percentages). - * - SET: Specify string in the format "top left", i.e. "25 70" (percentages). + * - SET: Specify string in the format "top left", i.e. "25 70" or "top left zoom", i.e. "25 70 30" (percentages). + * - SET: Specify CSV key=value string in the format "top=25%, left=70%, zoom=30%" in any order * - UNSET: Specify boolean false to remove any focus values. * @param null|float|int $left Set left value (when $top value is float|int) * - This argument is only used when setting focus and should be omitted otherwise. @@ -214,16 +218,29 @@ class Pageimage extends Pagefile { */ public function focus($top = null, $left = null, $zoom = null) { - if(is_string($top) && strpos($top, ' ') && $left === null) { - // SET string like "25 70 0" (representing "top left zoom") - if(strpos($top, ' ') != strrpos($top, ' ')) { - // with zoom - list($top, $left, $zoom) = explode(' ', $top, 3); - } else { - // without zoom - list($top, $left) = explode(' ', $top, 2); - $zoom = 0; - } + if(is_string($top) && $left === null) { + if(strpos($top, '=')) { + // SET string "top=25%, left=70%, zoom=0%" + $a = array('top' => 50, 'left' => 50, 'zoom' => 0); + $parts = explode(',', str_replace(array(' ', '%'), '', $top)); + foreach($parts as $part) { + if(!strpos($part, '=')) continue; + list($name, $pct) = explode('=', $part); + $a[$name] = strpos($pct, '.') !== false ? (float) $pct : (int) $pct; + } + $top = $a; // for later setting by array + unset($a); + } else if(strpos($top, ' ')) { + // SET string like "25 70 0" (representing "top left zoom") + if(strpos($top, ' ') != strrpos($top, ' ')) { + // with zoom + list($top, $left, $zoom) = explode(' ', $top, 3); + } else { + // without zoom + list($top, $left) = explode(' ', $top, 2); + $zoom = 0; + } + } } if($top === null || $top === true || ($top === 1 && $left === null)) { @@ -324,9 +341,19 @@ class Pageimage extends Pagefile { case 'focus': $value = $this->focus(); break; + case 'focusStr': + $focus = $this->focus(); + $value = "top=$focus[top]%,left=$focus[left]%,zoom=$focus[zoom]%" . ($focus['default'] ? " (default)" : ""); + break; case 'hasFocus': $value = $this->focus(true); break; + case 'suffix': + $value = $this->suffix(); + break; + case 'suffixStr': + $value = implode(',', $this->suffix()); + break; default: $value = parent::get($key); } @@ -1012,7 +1039,10 @@ class Pageimage extends Pagefile { * #pw-group-variations * * @param array $options Optional, one or more options in an associative array of the following: - * - `info` (bool): when true, method returns variation info arrays rather than Pageimage objects + * - `info` (bool): when true, method returns variation info arrays rather than Pageimage objects (default=false). + * - `verbose` (bool): Return verbose array of info. If false, returns only filenames (default=true). + * This option does nothing unless the `info` option is true. Also note that if verbose is false, then all options + * following this one no longer apply (since it is no longer returning width/height info). * - `width` (int): only variations with given width will be returned * - `height` (int): only variations with given height will be returned * - `width>=` (int): only variations with width greater than or equal to given will be returned @@ -1027,15 +1057,26 @@ class Pageimage extends Pagefile { public function getVariations(array $options = array()) { if(!is_null($this->variations)) return $this->variations; - - $variations = $this->wire(new Pageimages($this->pagefiles->page)); + + $defaults = array( + 'info' => false, + 'verbose' => true, + ); + + $options = array_merge($defaults, $options); + if(!$options['verbose'] && !$options['info']) $options['verbose'] = true; // non-verbose only allowed if info==true + $variations = $options['info'] ? null : $this->wire(new Pageimages($this->pagefiles->page)); $dir = new \DirectoryIterator($this->pagefiles->path); $infos = array(); foreach($dir as $file) { if($file->isDir() || $file->isDot()) continue; - $info = $this->isVariation($file->getFilename()); + $info = $this->isVariation($file->getFilename(), array('verbose' => $options['verbose'])); if(!$info) continue; + if($options['info'] && !$options['verbose']) { + $infos[] = $info; + continue; + } $allow = true; if(count($options)) foreach($options as $option => $value) { switch($option) { @@ -1238,11 +1279,21 @@ class Pageimage extends Pagefile { * #pw-group-variations * * @param string $basename Filename to check (basename, which excludes path) - * @param bool $allowSelf When true, it will return variation info even if same as current Pageimage. - * @return bool|array Returns false if not a variation, or array of info if it is. + * @param array|bool $options Array of options to modify behavior, or boolean to only specify `allowSelf` option. + * - `allowSelf` (bool): When true, it will return variation info even if same as current Pageimage. (default=false) + * - `verbose` (bool): Return verbose array of info? If false, just returns basename (string) or false. (default=true) + * @return bool|string|array Returns false if not a variation, or array (verbose) or string (non-verbose) of info if it is. * */ - public function ___isVariation($basename, $allowSelf = false) { + public function ___isVariation($basename, $options = array()) { + + $defaults = array( + 'allowSelf' => false, + 'verbose' => true, + ); + + if(!is_array($options)) $options = array('allowSelf' => (bool) $options); + $options = array_merge($defaults, $options); static $level = 0; $variationName = basename($basename); @@ -1264,11 +1315,14 @@ class Pageimage extends Pagefile { } // if file is the same as the original, then it's not a variation - if(!$allowSelf && $variationName == $this->basename) return false; + if(!$options['allowSelf'] && $variationName == $this->basename) return false; // if file doesn't start with the original name then it's not a variation if(strpos($variationName, $originalName) !== 0) return false; + // if not in verbose mode, just return variation file name + if(!$options['verbose']) return $variationName; + // get down to the meat and the base // meat is the part of the filename containing variation info like dimensions, crop, suffix, etc. // base is the part before that, which may include parent meat @@ -1353,8 +1407,8 @@ class Pageimage extends Pagefile { $actualInfo = $this->getImageInfo($info['path']); $info['actualWidth'] = $actualInfo['width']; $info['actualHeight'] = $actualInfo['height']; - $info['hidpiWidth'] = $this->hidpiWidth(0, $info['width']); - $info['hidpiHeight'] = $this->hidpiWidth(0, $info['height']); + $info['hidpiWidth'] = $this->hidpiWidth(0, $info['actualWidth']); + $info['hidpiHeight'] = $this->hidpiWidth(0, $info['actualHeight']); if(empty($info['crop'])) { // attempt to extract crop info from suffix @@ -1485,5 +1539,35 @@ class Pageimage extends Pagefile { } } + /** + * Debug info + * + * @return array + * + */ + public function __debugInfo() { + static $depth = 0; + $depth++; + $info = parent::__debugInfo(); + $info['width'] = $this->width(); + $info['height'] = $this->height(); + $info['suffix'] = $this->suffixStr; + if($this->hasFocus) $info['focus'] = $this->focusStr; + if(isset($info['filedata']) && isset($info['filedata']['focus'])) unset($info['filedata']['focus']); + if(empty($info['filedata'])) unset($info['filedata']); + $original = $this->original; + if($original && $original !== $this) $info['original'] = $original->basename; + if($depth < 2) { + $info['variations'] = array(); + $variations = $this->getVariations(array('info' => true, 'verbose' => false)); + foreach($variations as $name) { + $info['variations'][] = $name; + } + if(empty($info['variations'])) unset($info['variations']); + } + $depth--; + return $info; + } + }