/**
  * do the resizes like Pageimage does it
  *
  * @param object $caller
  * @param pageimage $img
  * @param string $targetFilename
  * @param array $options1
  * @param array $options2
  * @return pageimage
  */
 public static function renderImage(&$caller, &$img, $sourceFilename, $targetFilename, $width, $height, $options)
 {
     $filenameFinal = $targetFilename;
     $filenameUnvalidated = $img->pagefiles->page->filesManager()->getTempPath() . basename($targetFilename);
     if (file_exists($filenameFinal)) {
         @unlink($filenameFinal);
     }
     if (file_exists($filenameUnvalidated)) {
         @unlink($filenameUnvalidated);
     }
     if (@copy($sourceFilename, $filenameUnvalidated)) {
         try {
             $sizer = new ImageSizer($filenameUnvalidated);
             $sizer->setOptions($options);
             if ($sizer->resize($width, $height) && @rename($filenameUnvalidated, $filenameFinal)) {
                 // if script runs into a timeout while in ImageSizer, we never will reach this line and we will stay with $filenameUnvalidated
                 if ($caller->config->chmodFile) {
                     chmod($filenameFinal, octdec($caller->config->chmodFile));
                 }
             } else {
                 $caller->error = "ImageSizer::resize({$width}, {$height}) failed for {$filenameUnvalidated}";
             }
         } catch (Exception $e) {
             $caller->error = $e->getMessage();
         }
     } else {
         $caller->error("Unable to copy {$sourceFilename} => {$filenameUnvalidated}");
     }
     $pageimage = clone $img;
     // if desired, user can check for property of $pageimage->error to see if an error occurred.
     // if an error occurred, that error property will be populated with details
     if ($caller->error) {
         // error condition: unlink copied file
         if (is_file($filenameFinal)) {
             @unlink($filenameFinal);
         }
         if (is_file($filenameUnvalidated)) {
             @unlink($filenameUnvalidated);
         }
         // write an invalid image so it's clear something failed
         $data = "This is intentionally invalid image data.\n{$caller->error}";
         if (file_put_contents($filenameFinal, $data) !== false) {
             wireChmod($filenameFinal);
         }
         // we also tell PW about it for logging and/or admin purposes
         $caller->error($caller->error);
     }
     $pageimage->setFilename($filenameFinal);
     $pageimage->setOriginal($img);
     return $pageimage;
 }
Example #2
0
 /**
  * Hookable version of size() with implementation
  *	
  * See comments for size() method above.
  * 
  * @param int $width
  * @param int $height
  * @param array|string|int $options
  * @return Pageimage
  *
  */
 protected function ___size($width, $height, $options)
 {
     // I was getting unnecessarily resized images without this code below,
     // but this may be better solved in ImageSizer?
     /*
     $w = $this->width();
     $h = $this->height();
     if($w == $width && $h == $height) return $this; 
     if(!$height && $w == $width) return $this; 
     if(!$width && $h == $height) return $this; 
     */
     if ($this->ext == 'svg') {
         return $this;
     }
     if (!is_array($options)) {
         if (is_string($options)) {
             // optionally allow a string to be specified with crop direction, for shorter syntax
             if (strpos($options, ',') !== false) {
                 $options = explode(',', $options);
             }
             // 30,40
             $options = array('cropping' => $options);
         } else {
             if (is_int($options)) {
                 // optionally allow an integer to be specified with quality, for shorter syntax
                 $options = array('quality' => $options);
             } else {
                 if (is_bool($options)) {
                     // optionally allow a boolean to be specified with upscaling toggle on/off
                     $options = array('upscaling' => $options);
                 } else {
                     // unknown options type
                     $options = array();
                 }
             }
         }
     }
     $defaultOptions = array('upscaling' => true, 'cropping' => true, 'quality' => 90, 'hidpiQuality' => 40, 'suffix' => array(), 'forceNew' => false, 'hidpi' => false, 'cleanFilename' => false, 'rotate' => 0, 'flip' => '');
     $this->error = '';
     $configOptions = wire('config')->imageSizerOptions;
     if (!is_array($configOptions)) {
         $configOptions = array();
     }
     $options = array_merge($defaultOptions, $configOptions, $options);
     $width = (int) $width;
     $height = (int) $height;
     if (is_string($options['cropping']) && strpos($options['cropping'], 'x') === 0 && preg_match('/^x(\\d+)[yx](\\d+)/', $options['cropping'], $matches)) {
         $options['cropping'] = true;
         $options['cropExtra'] = array((int) $matches[1], (int) $matches[2], $width, $height);
         $crop = '';
     } else {
         $crop = ImageSizer::croppingValueStr($options['cropping']);
     }
     if (!is_array($options['suffix'])) {
         // convert to array
         $options['suffix'] = empty($options['suffix']) ? array() : explode(' ', $options['suffix']);
     }
     if ($options['rotate'] && !in_array(abs((int) $options['rotate']), array(90, 180, 270))) {
         $options['rotate'] = 0;
     }
     if ($options['rotate']) {
         $options['suffix'][] = ($options['rotate'] > 0 ? "rot" : "tor") . abs($options['rotate']);
     }
     if ($options['flip']) {
         $options['suffix'][] = strtolower(substr($options['flip'], 0, 1)) == 'v' ? 'flipv' : 'fliph';
     }
     $suffixStr = '';
     if (!empty($options['suffix'])) {
         $suffix = $options['suffix'];
         sort($suffix);
         foreach ($suffix as $key => $s) {
             $s = strtolower($this->wire('sanitizer')->fieldName($s));
             if (empty($s)) {
                 unset($suffix[$key]);
             } else {
                 $suffix[$key] = $s;
             }
         }
         if (count($suffix)) {
             $suffixStr = '-' . implode('-', $suffix);
         }
     }
     if ($options['hidpi']) {
         $suffixStr .= '-hidpi';
         if ($options['hidpiQuality']) {
             $options['quality'] = $options['hidpiQuality'];
         }
     }
     //$basename = $this->pagefiles->cleanBasename($this->basename(), false, false, false);
     // cleanBasename($basename, $originalize = false, $allowDots = true, $translate = false)
     $basename = basename($this->basename(), "." . $this->ext());
     // i.e. myfile
     if ($options['cleanFilename'] && strpos($basename, '.') !== false) {
         $basename = substr($basename, 0, strpos($basename, '.'));
     }
     $basename .= '.' . $width . 'x' . $height . $crop . $suffixStr . "." . $this->ext();
     // i.e. myfile.100x100.jpg or myfile.100x100nw-suffix1-suffix2.jpg
     $filenameFinal = $this->pagefiles->path() . $basename;
     $filenameUnvalidated = '';
     $exists = file_exists($filenameFinal);
     if (!$exists || $options['forceNew']) {
         $filenameUnvalidated = $this->pagefiles->page->filesManager()->getTempPath() . $basename;
         if ($exists && $options['forceNew']) {
             @unlink($filenameFinal);
         }
         if (file_exists($filenameUnvalidated)) {
             @unlink($filenameUnvalidated);
         }
         if (@copy($this->filename(), $filenameUnvalidated)) {
             try {
                 $sizer = new ImageSizer($filenameUnvalidated);
                 $sizer->setOptions($options);
                 if ($sizer->resize($width, $height) && @rename($filenameUnvalidated, $filenameFinal)) {
                     wireChmod($filenameFinal);
                 } else {
                     $this->error = "ImageSizer::resize({$width}, {$height}) failed for {$filenameUnvalidated}";
                 }
             } catch (Exception $e) {
                 $this->trackException($e, false);
                 $this->error = $e->getMessage();
             }
         } else {
             $this->error("Unable to copy {$this->filename} => {$filenameUnvalidated}");
         }
     }
     $pageimage = clone $this;
     // if desired, user can check for property of $pageimage->error to see if an error occurred.
     // if an error occurred, that error property will be populated with details
     if ($this->error) {
         // error condition: unlink copied file
         if (is_file($filenameFinal)) {
             @unlink($filenameFinal);
         }
         if ($filenameUnvalidated && is_file($filenameUnvalidated)) {
             @unlink($filenameUnvalidated);
         }
         // write an invalid image so it's clear something failed
         // todo: maybe return a 1-pixel blank image instead?
         $data = "This is intentionally invalid image data.\n{$this->error}";
         if (file_put_contents($filenameFinal, $data) !== false) {
             wireChmod($filenameFinal);
         }
         // we also tell PW about it for logging and/or admin purposes
         $this->error($this->error);
     }
     $pageimage->setFilename($filenameFinal);
     $pageimage->setOriginal($this);
     return $pageimage;
 }
Example #3
0
 /**
  * Hookable version of size() with implementation
  *	
  * See comments for size() method above. 
  *
  */
 protected function ___size($width, $height, $options)
 {
     // I was getting unnecessarily resized images without this code below,
     // but this may be better solved in ImageSizer?
     /*
     $w = $this->width();
     $h = $this->height();
     if($w == $width && $h == $height) return $this; 
     if(!$height && $w == $width) return $this; 
     if(!$width && $h == $height) return $this; 
     */
     if ($this->ext == 'svg') {
         return $this;
     }
     if (!is_array($options)) {
         if (is_string($options)) {
             // optionally allow a string to be specified with crop direction, for shorter syntax
             if (strpos($options, ',') !== false) {
                 $options = explode(',', $options);
             }
             // 30,40
             $options = array('cropping' => $options);
         } else {
             if (is_int($options)) {
                 // optionally allow an integer to be specified with quality, for shorter syntax
                 $options = array('quality' => $options);
             } else {
                 if (is_bool($options)) {
                     // optionally allow a boolean to be specified with upscaling toggle on/off
                     $options = array('upscaling' => $options);
                 }
             }
         }
     }
     $defaultOptions = array('upscaling' => true, 'cropping' => true, 'quality' => 90, 'suffix' => array(), 'forceNew' => false);
     $this->error = '';
     $configOptions = wire('config')->imageSizerOptions;
     if (!is_array($configOptions)) {
         $configOptions = array();
     }
     $options = array_merge($defaultOptions, $configOptions, $options);
     $width = (int) $width;
     $height = (int) $height;
     $crop = ImageSizer::croppingValueStr($options['cropping']);
     $suffixStr = '';
     if (!empty($options['suffix'])) {
         $suffix = is_array($options['suffix']) ? $options['suffix'] : array($options['suffix']);
         sort($suffix);
         foreach ($suffix as $key => $s) {
             $s = strtolower($this->wire('sanitizer')->fieldName($s));
             if (empty($s)) {
                 unset($suffix[$key]);
             } else {
                 $suffix[$key] = $s;
             }
         }
         if (count($suffix)) {
             $suffixStr = '-' . implode('-', $suffix);
         }
     }
     $basename = basename($this->basename(), "." . $this->ext());
     // i.e. myfile
     $basename .= '.' . $width . 'x' . $height . $crop . $suffixStr . "." . $this->ext();
     // i.e. myfile.100x100.jpg or myfile.100x100nw-suffix1-suffix2.jpg
     $filename = $this->pagefiles->path() . $basename;
     $exists = file_exists($filename);
     if (!$exists || $options['forceNew']) {
         if ($exists && $options['forceNew']) {
             unlink($filename);
         }
         if (@copy($this->filename(), $filename)) {
             try {
                 $sizer = new ImageSizer($filename);
                 $sizer->setOptions($options);
                 if ($sizer->resize($width, $height)) {
                     if ($this->config->chmodFile) {
                         chmod($filename, octdec($this->config->chmodFile));
                     }
                 } else {
                     $this->error = "ImageSizer::resize({$width}, {$height}) failed for {$filename}";
                 }
             } catch (Exception $e) {
                 $this->error = $e->getMessage();
             }
         } else {
             $this->error("Unable to copy {$this->filename} => {$filename}");
         }
     }
     $pageimage = clone $this;
     // if desired, user can check for property of $pageimage->error to see if an error occurred.
     // if an error occurred, that error property will be populated with details
     if ($this->error) {
         // error condition: unlink copied file
         if (is_file($filename)) {
             unlink($filename);
         }
         // write an invalid image so it's clear something failed
         // todo: maybe return a 1-pixel blank image instead?
         $data = "This is intentionally invalid image data.\n{$this->error}";
         if (file_put_contents($filename, $data) !== false) {
             wireChmod($filename);
         }
         // we also tell PW about it for logging and/or admin purposes
         $this->error($this->error);
     }
     $pageimage->setFilename($filename);
     $pageimage->setOriginal($this);
     return $pageimage;
 }
Example #4
0
 /**
  * Return a Pageimage object sized/cropped to the specified dimensions. 
  *
  * The 3rd argument $options may be an array, string, integer or boolean. When an array, you may specify multiple options
  * to override. These include: 'quality', 'upscaling', and 'cropping'. When a string, it is assumed you are specifying
  * a cropping value. When an integer, it is assumed you are specifying a quality value. When a boolean, it is assumed you
  * are specifying an 'upscaling' toggle on/off. 
  *
  * Cropping may be specified either in the options array with the 'cropping' index, or via a 3rd string param to the function.
  * Possible values for 'cropping' include: northwest, north, northeast, west, center, east, southwest, south, southeast.
  * If you prefer, you can specify shorter versions like 'nw' for 'northwest', or 's' for 'south', etc. 
  * If cropping is not specified, then 'center' is assumed. 
  * To completely disable cropping, specify a blank string.
  *
  * Quality may be specified either in the options array with the 'quality' index, or via a 3rd integer param to the function.
  * Possible values for 'quality' are 1 to 100. Default is 90. Important: See the PLEASE NOTE section below.
  *
  * Upscaling may be specified either in the options array with the 'upscaling' index, or via a 3rd boolean param to the function.
  * Possible values for 'upscaling' are TRUE and FALSE. Default is TRUE. Important: See the PLEASE NOTE section below.
  *
  * PLEASE NOTE: ProcessWire doesn't keep separate copies of images with different 'quality' or 'upscaling' values. If you change
  * these and a variation image at the existing dimensions already exists, then you'll still get the old version. 
  * To clear out an old version of an image, use the removeVariations() method in this class before calling size() with new 
  * quality or upscaling settings.
  *
  * @param int $width
  * @param int $height
  * @param array|string|int $options Array of options to override default behavior (quality=90, upscaling=true, cropping=center).
  *	Or you may specify a string|bool with with 'cropping' value if you don't need to combine with other options.
  *	Or you may specify an integer with 'quality' value if you don't need to combine with other options.
  * 	Or you may specify a boolean with 'upscaling' value if you don't need to combine with other options.
  * @return Pageimage
  *
  */
 public function size($width, $height, $options = array())
 {
     if (!is_array($options)) {
         if (is_string($options)) {
             // optionally allow a string to be specified with crop direction, for shorter syntax
             if (strpos($options, ',') !== false) {
                 $options = explode(',', $options);
             }
             // 30,40
             $options = array('cropping' => $options);
         } else {
             if (is_int($options)) {
                 // optionally allow an integer to be specified with quality, for shorter syntax
                 $options = array('quality' => $options);
             } else {
                 if (is_bool($options)) {
                     // optionally allow a boolean to be specified with upscaling toggle on/off
                     $options = array('upscaling' => $options);
                 }
             }
         }
     }
     $defaultOptions = array('upscaling' => true, 'cropping' => true, 'quality' => 90);
     $configOptions = wire('config')->imageSizerOptions;
     if (!is_array($configOptions)) {
         $configOptions = array();
     }
     $options = array_merge($defaultOptions, $configOptions, $options);
     $width = (int) $width;
     $height = (int) $height;
     $crop = ImageSizer::croppingValueStr($options['cropping']);
     $basename = basename($this->basename(), "." . $this->ext());
     // i.e. myfile
     $basename .= '.' . $width . 'x' . $height . $crop . "." . $this->ext();
     // i.e. myfile.100x100.jpg or myfile.100x100nw.jpg
     $filename = $this->pagefiles->path() . $basename;
     if (!is_file($filename)) {
         if (@copy($this->filename(), $filename)) {
             try {
                 $sizer = new ImageSizer($filename);
                 $sizer->setOptions($options);
                 $sizer->resize($width, $height);
             } catch (Exception $e) {
                 $this->error($e->getMessage());
             }
             if ($this->config->chmodFile) {
                 chmod($filename, octdec($this->config->chmodFile));
             }
         }
     }
     $pageimage = clone $this;
     $pageimage->setFilename($filename);
     $pageimage->setOriginal($this);
     return $pageimage;
 }