setCrop($options['crop']);
}
if (!empty($options['lazy_load'])) {
$this->setLazyLoad($options['lazy_load']);
}
}
/**
*
* get file name
*
* @return string
*/
public function getName()
{
return $this->_name;
}
/**
*
* set file name
*
* @param string $name
*
* @return $this
*/
public function setName($name)
{
$name = preg_replace("/[^a-zA-Z0-9_-]/", '', $name);
$this->_name = (string)$name;
return $this;
}
/**
*
* get file extension
*
* @return string
*/
public function getExtension()
{
return $this->_extension;
}
/**
*
* set file extension
*
* @param string $extension
*
* @return $this
*/
public function setExtension($extension)
{
if (!in_array($extension, $this->_extensions)) {
$extension = self::DEFAULT_EXTENSION;
}
$this->_extension = (string)$extension;
return $this;
}
/**
*
* get destination thumbnail width
*
* @return integer
*/
public function getWidth()
{
return $this->_width;
}
/**
*
* set destination thumbnail width
*
* @param int $width
*
* @return $this
*/
public function setWidth($width)
{
$width = intval($width);
if ($width < self::MIN_WIDTH) {
$width = self::MIN_WIDTH;
}
if ($width > self::MAX_WIDTH && self::MAX_WIDTH > 0) {
$width = self::MAX_WIDTH;
}
$this->_width = $width;
return $this;
}
/**
*
* get destination thumbnail height
*
* @return bool
*/
public function getHeight()
{
return $this->_height;
}
/**
*
* set destination thumbnail height
*
* @param integer|boolean $height
*
* @return $this
*/
public function setHeight($height = true)
{
$this->_height = $height;
return $this;
}
/**
*
* set square option (legacy method)
*
* @param bool $square
*
* @return $this
*/
public function setSquare($square = true)
{
$this->setHeight((bool)$square);
return $this;
}
/**
*
* get crop option
*
* @return boolean
*/
public function getCrop()
{
return $this->_crop;
}
/**
*
* set crop option
*
* @param boolean $crop
*
* @return $this
*/
public function setCrop($crop = true)
{
$this->_crop = (bool)$crop;
return $this;
}
/**
*
* check lazy load plugin flag
*
* @return bool
*/
public function isLazyLoad()
{
return $this->_lazyLoad;
}
/**
*
* set lazy load plugin flag
*
* @param bool $lazyLoad
*
* @return $this
*/
public function setLazyLoad($lazyLoad)
{
$this->_lazyLoad = $lazyLoad;
return $this;
}
/**
*
* get base url
*
* @return string
*/
public function getBaseUrl()
{
if ($this->_baseUrl === null) {
$this->setBaseUrl(
Front::getInstance()->getRequest()->getBaseUrl());
}
return $this->_baseUrl;
}
/**
*
* set base url
*
* @param string $baseUrl
*
* @return $this
*/
public function setBaseUrl($baseUrl)
{
$this->_baseUrl = $baseUrl;
return $this;
}
/**
*
* generate cached thumbnail and return image link
* (has backwards compatibility for v6's uplimg folder)
*
* @param string $image
* @param int|null $width
* @param bool|int|null $height
* @param array $params
*
* @return string
*/
public function generateLink($image, $width = null, $height = null, $params = array())
{
$this->setWidth($width)
->setHeight($height);
$type = (isset($params['type'])) ? $params['type'] : Service\ListingsMedia::TYPE_IMAGE;
$crop = (isset($params['crop'])) ? $params['crop'] : null;
switch ($type) {
case Service\ListingsMedia::TYPE_VIDEO:
$image = \Ppb\Utility::getPath('img') . \Ppb\Utility::URI_DELIMITER . self::VIDEO_PLACEHOLDER;
break;
case Service\ListingsMedia::TYPE_DOWNLOAD:
$image = \Ppb\Utility::getPath('img') . \Ppb\Utility::URI_DELIMITER . self::DOWNLOAD_PLACEHOLDER;
break;
case Service\ListingsMedia::TYPE_CSV:
$image = \Ppb\Utility::getPath('img') . \Ppb\Utility::URI_DELIMITER . self::CSV_PLACEHOLDER;
break;
default:
if ($image == null) {
$image = \Ppb\Utility::getPath('img') . \Ppb\Utility::URI_DELIMITER . self::IMAGE_PLACEHOLDER;
}
else {
if (!preg_match('#^http(s)?://(.*)+$#i', $image) && !preg_match('#^uplimg/(.*)+$#i', $image)) {
$image = \Ppb\Utility::getFolder('uploads') . \Ppb\Utility::URI_DELIMITER . $image;
}
}
break;
}
return $this->getBaseUrl() . \Ppb\Utility::URI_DELIMITER
. \Ppb\Utility::getFolder('cache') . \Ppb\Utility::URI_DELIMITER
. $this->_generateThumb($image, $crop);
}
/**
*
* generates a path to a media file
* if we have a remote image or a v6 image, return the path unmodified
*
* @param string $image
*
* @return string
*/
public function generateImagePath($image)
{
if (preg_match('#^uplimg/(.*)+$#i', $image)) {
// we have a v6 image - add base url
return $this->getBaseUrl() . '/' . $image;
}
else if (!preg_match('#^http(s)?://(.*)+$#i', $image)) {
// we have a v7 image - add base url and uploads folder
return $this->getBaseUrl() . \Ppb\Utility::URI_DELIMITER
. \Ppb\Utility::getFolder('uploads') . \Ppb\Utility::URI_DELIMITER
. $image;
}
return $image;
}
/**
*
* check whether the uploaded file is an image
*
* @param string $fileName
*
* @return bool
*/
public function isImage($fileName)
{
$fileInfo = @getimagesize($fileName);
if ($fileInfo === false || $fileInfo[2] > 3) {
return false;
}
return true;
}
/**
*
* output image using corresponding function based on mime
*
* @param mixed $output
* @param string $fileName
* @param string $mime
*
* @return $this
*/
public function imageOutputFunction($output, $fileName, $mime = null)
{
if ($mime === null) {
$imgInfo = @getimagesize($fileName);
$mime = $imgInfo['mime'];
}
switch ($mime) {
case 'image/gif':
$imageOutputFunction = 'imagegif';
break;
case 'image/png':
$imageOutputFunction = 'imagepng';
break;
default:
$imageOutputFunction = 'imagejpeg';
break;
}
touch($fileName);
$imageOutputFunction($output, $fileName);
imagedestroy($output);
return $this;
}
/**
*
* image create function based on source image type
*
* @param string $fileName
* @param string $mime
*
* @return mixed
*/
public function imageCreateFunction($fileName, $mime = null)
{
if ($mime === null) {
$imgInfo = @getimagesize($fileName);
$mime = $imgInfo['mime'];
}
switch ($mime) {
case 'image/gif':
$imageCreateFunction = 'ImageCreateFromGIF';
break;
case 'image/png':
$imageCreateFunction = 'ImageCreateFromPNG';
break;
default:
$imageCreateFunction = 'ImageCreateFromJPEG';
break;
}
return $imageCreateFunction($fileName);
}
/**
*
* create resized image
*
* @param string $srcImage
* @param bool|null $crop
*
* @return resource
*/
public function createResizedImage($srcImage, $crop = null)
{
$fileName = null;
$imgInfo = @getimagesize($srcImage);
list($srcWidth, $srcHeight, $imgType) = $imgInfo;
if ($imgInfo === false || $imgType > 3) {
$srcImage = \Ppb\Utility::getPath('img') . \Ppb\Utility::URI_DELIMITER . self::BROKEN_IMAGE;
$imgInfo = @getimagesize($srcImage);
list($srcWidth, $srcHeight, $imgType) = $imgInfo;
}
if ($crop === null) {
$crop = $this->getCrop();
}
$dstWidth = $tmpWidth = $this->getWidth();
$dstHeight = $this->getHeight();
$tmpHeight = round(($dstWidth * $srcHeight) / $srcWidth);
if ($dstHeight === true) {
$dstHeight = $dstWidth;
}
else if (!is_numeric($dstHeight)) {
$dstHeight = $tmpHeight;
}
$image = $this->imageCreateFunction($srcImage, $imgInfo['mime']);
if (!$image) {
$output = imagecreate($dstWidth, $dstHeight); /* Create a blank image */
$white = imagecolorallocate($output, 255, 255, 255);
$black = imagecolorallocate($output, 0, 0, 0);
imagefilledrectangle($output, 0, 0, 150, 30, $white);
imagestring($output, 1, 5, 5, 'Error loading ' . $srcImage, $black); /* Output an error message */
}
else {
$srcAspect = $srcWidth / $srcHeight;
$dstAspect = $dstWidth / $dstHeight;
/**
* cropping is disabled if source image has at least one side smaller than the destination image
*/
if ($srcHeight < $dstHeight || $srcWidth < $dstWidth) {
$crop = false;
}
/**
* if crop, then cut to fit, otherwise add white background to fit
*/
if (($crop && ($srcAspect > $dstAspect)) || (!$crop && ($srcAspect < $dstAspect))) {
$tmpHeight = $dstHeight;
$tmpWidth = round($dstHeight * $srcAspect);
}
else {
$tmpWidth = $dstWidth;
$tmpHeight = round($dstWidth / $srcAspect);
}
/**
* first we resize original image to desired dimensions
*/
$resized = imagecreatetruecolor($tmpWidth, $tmpHeight);
$backgroundColor = imagecolorallocate($resized, 255, 255, 255);
imagefill($resized, 0, 0, $backgroundColor);
imagecopyresampled(
$resized,
$image,
0, 0,
0, 0,
$tmpWidth, $tmpHeight,
$srcWidth, $srcHeight
);
$output = imagecreatetruecolor($dstWidth, $dstHeight);
/**
* now we either crop or add white background and output resulting image
*/
if ($crop) {
$srcX = ($tmpWidth - $dstWidth) / 2;
$srcY = ($tmpHeight - $dstHeight) / 2;
imagecopy(
$output,
$resized,
0, 0,
$srcX, $srcY,
$dstWidth, $dstHeight
);
}
else {
$backgroundColor = imagecolorallocate($output, 255, 255, 255);
imagefill($output, 0, 0, $backgroundColor);
$dstX = ($dstWidth - $tmpWidth) / 2;
$dstY = ($dstHeight - $tmpHeight) / 2;
imagecopy(
$output,
$resized,
$dstX, $dstY,
0, 0,
$tmpWidth, $tmpHeight
);
}
}
return $output;
}
/**
*
* rotate uploaded image automatically based on exif orientation
*
* @param string $fileName
*
* @return $this
*/
public function imageSmartRotate($fileName)
{
$output = null;
if (function_exists('exif_read_data')) {
$exif = @exif_read_data($fileName);
if (!empty($exif['Orientation'])) {
$image = $this->imageCreateFunction($fileName);
switch ($exif['Orientation']) {
case 3:
$output = imagerotate($image, 180, 255);
break;
case 6:
$output = imagerotate($image, -90, 255);
break;
case 8:
$output = imagerotate($image, 90, 255);
break;
}
if ($output !== null) {
$this->imageOutputFunction($output, $fileName);
}
}
}
return $this;
}
/**
*
* add watermark to the image
*
* @param string $fileName
* @param string $watermarkText
*
* @return $this
*/
public function addWatermark($fileName, $watermarkText)
{
if ($this->isImage($fileName)) {
$output = $this->imageCreateFunction($fileName);
// Get identifier for white
$white = imagecolorallocate($output, 255, 255, 255);
// Add text to image
imagestring($output, 20, 5, imagesy($output) - 20, $watermarkText, $white);
// Save the image to file and free memory
$this->imageOutputFunction($output, $fileName);
}
return $this;
}
/**
*
* the helper will display a thumbnail image,
* or in case media is uploaded, it will add a default thumbnail
*
* @param string $image
* @param int $width
* @param string $square (Y|N|null)
* @param array $params (reserved params: zoom, crop)
*
* @return mixed
*/
public function thumbnail($image = null, $width = null, $square = null, $params = array())
{
$dataSrc = null;
if ($image === null && $width === null && $square === null) {
return $this;
}
$zoom = (isset($params['zoom'])) ? $params['zoom'] : false;
if ($zoom === true) {
$dataSrc = 'data-src="' . $this->generateImagePath($image) . '" ';
// add js
/** @var \Cube\View\Helper\Script $helper */
$helper = $this->getView()->getHelper('script');
$helper->addBodyCode('')
->addBodyCode("");
}
$lazyLoad = (isset($params['lazyLoad']) && $this->isLazyLoad()) ? $params['lazyLoad'] : false;
if (!array_key_exists('class', $params)) {
$params['class'] = 'img-thumbnail img-responsive';
}
$src = $this->generateLink($image, $width, $square, $params);
if ($lazyLoad === true) {
// add js
/** @var \Cube\View\Helper\Script $helper */
$helper = $this->getView()->getHelper('script');
$helper->addBodyCode('')
->addBodyCode('');
$params['class'] .= ((!empty($params['class'])) ? ' ' : '') . 'b-lazy';
$dataSrc = 'data-src="' . $src . '" ';
$src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
}
foreach ($params as $key => $value) {
if (!in_array($key, $this->_reservedParams)) {
$dataSrc .= $key . '="' . str_replace('"', '', $value) . '" ';
}
}
return '_endTag;
}
/**
*
* generate cache file name
*
* @param string $name
* @param bool|null $crop
*
* @return string
*/
protected function _generateCacheName($name, $crop = null)
{
$extension = $this->getExtension();
$height = $this->getHeight();
$width = $this->getWidth();
if ($height === true) {
$height = $width;
}
if ($crop === null) {
$crop = $this->getCrop();
}
return $name . '-'
. $width
. (($height !== null) ? 'x' . $height : '')
. (($crop === true) ? '-' . 'crop' : '')
. '.'
. $extension;
}
/**
*
* generates a thumbnail of a given image, using the width and height parameters
*
* @param string $image
* @param bool|null $crop
*
* @return string
*/
protected function _generateThumb($image, $crop = null)
{
$fileName = null;
$pathInfo = pathinfo($image);
$baseName = (isset($pathInfo['filename'])) ? $pathInfo['filename'] : null;
$extension = (isset($pathInfo['extension'])) ? $pathInfo['extension'] : null;
if (preg_match('#^http(s)?://(.*)+$#i', $image)) {
$baseName = preg_replace('/[^\da-z]/i', '', $image);
}
$this->setName($baseName)
->setExtension($extension);
$cacheName = $this->_generateCacheName($baseName, $crop);
$cacheFilePath = \Ppb\Utility::getPath('cache') . DIRECTORY_SEPARATOR . $cacheName;
if (file_exists($cacheFilePath)) {
return $cacheName;
}
else {
$output = $this->createResizedImage($image, $crop);
$this->imageOutputFunction($output, $cacheFilePath);
$fileName = $cacheName;
return $fileName;
}
}
}