Files

611 lines
14 KiB
PHP
Executable File

<?php
/**
* Image helper
*
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Olegnax\BannerSlider\Helper;
use Exception;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\Image as MagentoImage;
use Magento\Framework\Image\AdapterFactory;
use Magento\Framework\Image\Factory;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;
/**
* Description of Image
*
* @author Master
*/
class Image extends AbstractHelper
{
protected $_baseFile;
/**
* @var int
*/
protected $_width;
/**
* @var int
*/
protected $_height;
/**
* Default quality value (for JPEG images only).
*
* @var int
*/
protected $_quality = 90;
/**
* @var bool
*/
protected $_keepAspectRatio = true;
/**
* @var bool
*/
protected $_keepFrame = true;
/**
* @var bool
*/
protected $_keepTransparency = true;
/**
* @var bool
*/
protected $_constrainOnly = true;
/**
* @var bool
*/
protected $_cropOnly = false;
/**
* @var int[]
*/
protected $_backgroundColor = [255, 255, 255];
/**
* @var MagentoImage
*/
protected $_processor;
/**
* @var string
*/
protected $_destinationSubdir;
/**
* @var WriteInterface
*/
protected $_mediaDirectory;
/**
* @var Factory
*/
protected $_imageFactory;
/**
* @var array
*/
protected $attributes;
/**
* @var AdapterFactory
*/
protected $adapterFactory;
/**
* @var string
*/
private $cachePrefix = 'IMG_INFO';
/**
* Store Manager
*
* @var StoreManagerInterface
*/
private $_storeManager;
public function __construct(
Filesystem $filesystem,
Factory $imageFactory,
StoreManagerInterface $storeManager,
AdapterFactory $adapterFactory
) {
$this->_mediaDirectory = $filesystem->getDirectoryRead(DirectoryList::MEDIA);
$this->_imageFactory = $imageFactory;
$this->_storeManager = $storeManager;
$this->adapterFactory = $adapterFactory;
}
/**
* @return bool
*/
public function checkDependencies() {
try {
$this->adapterFactory->create();
return true;
} catch (Exception $e) {
$this->_logger->critical($e->getMessage());
return false;
}
}
public function adaptiveResize($file, $size, $attributes = [])
{
if ($this->checkDependencies()) {
$this->init($file, $attributes);
[$width, $height] = $this->prepareSize($size);
$this->setWidth($width);
$this->setHeight($height);
if ($this->_keepAspectRatio && $this->_cropOnly) {
$this->crop();
}
$this->resize();
} else {
}
return $this;
}
public function init($file, $attributes = [])
{
$this->_processor = null;
$this->setBaseFile($file);
$this->attributes = $attributes;
$this->setImageProperties();
}
/**
* Set image properties
*
* @return $this
*/
protected function setImageProperties()
{
$this->setDestinationSubdir('resized');
// Set 'keep frame' flag
$frame = $this->getAttribute('frame');
if (!empty($frame)) {
$this->setKeepFrame($frame);
}
// Set 'constrain only' flag
$constrain = $this->getAttribute('constrain');
if (!empty($constrain)) {
$this->setConstrainOnly($constrain);
}
// Set 'keep aspect ratio' flag
$aspectRatio = $this->getAttribute('aspect_ratio');
if (!empty($aspectRatio)) {
$this->setKeepAspectRatio($aspectRatio);
}
// Set 'keep $crop' flag
$crop = $this->getAttribute('crop');
if (!empty($crop)) {
$this->seCropOnly($crop);
}
// Set 'transparency' flag
$transparency = $this->getAttribute('transparency');
if (!empty($transparency)) {
$this->setKeepTransparency($transparency);
}
// Set background color
$background = $this->getAttribute('background');
if (!empty($background)) {
$this->setBackgroundColor($background);
}
return $this;
}
/**
* Retrieve image attribute
*
* @param string $name
*
* @return string
*/
protected function getAttribute($name)
{
return $this->attributes[$name] ?? null;
}
/**
* @param bool $keep
*
* @return $this
*/
public function setKeepFrame($keep)
{
$this->_keepFrame = $keep && $keep !== 'false';
return $this;
}
/**
* @param bool $flag
*
* @return $this
*/
public function setConstrainOnly($flag)
{
$this->_constrainOnly = $flag && $flag !== 'false';
return $this;
}
/**
* @param bool $keep
*
* @return $this
*/
public function setKeepAspectRatio($keep)
{
$this->_keepAspectRatio = $keep && $keep !== 'false';
return $this;
}
/**
* @param bool $flag
*
* @return $this
*/
public function seCropOnly($flag)
{
$this->_cropOnly = $flag && $flag !== 'false';
return $this;
}
/**
* @param bool $keep
*
* @return $this
*/
public function setKeepTransparency($keep)
{
$this->_keepTransparency = $keep && $keep !== 'false';
return $this;
}
/**
* @param int[] $rgbArray
*
* @return $this
*/
public function setBackgroundColor(array $rgbArray)
{
$this->_backgroundColor = $rgbArray;
return $this;
}
private function prepareSize($size)
{
if (is_array($size) && 1 >= count($size)) {
$size = array_shift($size);
}
if (!is_array($size)) {
$size = [$size, $size];
}
$size = array_map('intval', $size);
$size = array_map('abs', $size);
return $size;
}
public function crop()
{
if (($this->getWidth() === null && $this->getHeight() === null) || !$this->getBaseFile()) {
return $this;
}
if ($this->_fileExists($this->getResizedFile())) {
return $this;
}
$_imageSrcWidth = $this->getImageProcessor()->getOriginalWidth();
$_imageSrcHeight = $this->getImageProcessor()->getOriginalHeight();
$_imageSrcRatio = $_imageSrcWidth / $_imageSrcHeight;
$_ratio = $this->_width / $this->_height;
if ($_imageSrcRatio != $_ratio) {
if (1 > $_imageSrcRatio) {
$newHeight = round($_imageSrcWidth / $_ratio);
$deltHeight = $_imageSrcHeight - $newHeight;
$_deltHeight = floor($deltHeight / 2);
$__deltHeight = $deltHeight % 2;
$this->getImageProcessor()->crop($_deltHeight + $__deltHeight, 0, 0, $_deltHeight);
} elseif (1 < $_imageSrcRatio) {
$newWidth = round($_imageSrcHeight * $_ratio);
$deltWidth = $_imageSrcWidth - $newWidth;
$_deltWidth = floor($deltWidth / 2);
$__deltWidth = $deltWidth % 2;
$this->getImageProcessor()->crop(0, $_deltWidth + $__deltWidth, $_deltWidth, 0);
}
}
return $this;
}
/**
* @return int
*/
public function getWidth()
{
return $this->_width;
}
/**
* @param int $width
*
* @return $this
*/
public function setWidth($width)
{
$this->_width = $width;
return $this;
}
/**
* @return int
*/
public function getHeight()
{
return $this->_height;
}
/**
* @param int $height
*
* @return $this
*/
public function setHeight($height)
{
$this->_height = $height;
return $this;
}
/**
* @return string
*/
public function getBaseFile()
{
return $this->_baseFile;
}
/**
* Set filenames for base file and new file
*
* @param string $file
*
* @return $this
* @throws Exception
*/
public function setBaseFile($file)
{
if ($this->_fileExists($file)) {
$this->_baseFile = $file;
}
return $this;
}
/**
* First check this file on FS
* If it doesn't exist - try to download it from DB
*
* @param string $filename
*
* @return bool
*/
protected function _fileExists($filename)
{
return file_exists($this->_mediaDirectory->getAbsolutePath($filename));
}
private function getResizedFile()
{
$new_filename = pathinfo($this->getBaseFile());
if (is_array($new_filename) && !empty($new_filename)) {
$new_filename['filename'] = implode('_', [
$new_filename['filename'],
$this->getWidth(),
$this->getHeight()
]) . '.' . $new_filename['extension'];
return implode('/', [$this->getDestinationSubdir(), $new_filename['dirname'], $new_filename['filename']]);
}
return '';
}
/**
* @return string
*/
public function getDestinationSubdir()
{
return $this->_destinationSubdir;
}
/**
* @param string $dir
*
* @return $this
*/
public function setDestinationSubdir($dir)
{
$this->_destinationSubdir = $dir;
return $this;
}
/**
* @return MagentoImage
*/
public function getImageProcessor()
{
if (!$this->_processor) {
$filename = $this->getBaseFile() ? $this->_mediaDirectory->getAbsolutePath($this->getBaseFile()) : null;
$this->_processor = $this->_imageFactory->create($filename);
}
$this->_processor->keepAspectRatio($this->_keepAspectRatio);
$this->_processor->keepFrame($this->_keepFrame);
$this->_processor->keepTransparency($this->_keepTransparency);
$this->_processor->constrainOnly($this->_constrainOnly);
$this->_processor->backgroundColor($this->_backgroundColor);
$this->_processor->quality($this->_quality);
return $this->_processor;
}
/**
* @return $this
* @see \Magento\Framework\Image\Adapter\AbstractAdapter
*/
public function resize()
{
if ($this->getWidth() === null && $this->getHeight() === null
|| !$this->getBaseFile()
|| !$this->_fileExists($this->getBaseFile())) {
return $this;
}
$resizedFile = $this->getResizedFile();
if ($resizedFile && $this->_fileExists($resizedFile)) {
return $this;
}
$new_filename = $this->_mediaDirectory->getAbsolutePath($resizedFile);
$this->getImageProcessor()->resize($this->_width, $this->_height);
$this->getImageProcessor()->save($new_filename);
return $this;
}
/**
* @param MagentoImage $processor
*
* @return $this
*/
public function setImageProcessor($processor)
{
$this->_processor = $processor;
return $this;
}
/**
* Get image quality
*
* @return int
*/
public function getQuality()
{
return $this->_quality;
}
/**
* Set image quality, values in percentage from 0 to 100
*
* @param int $quality
*
* @return $this
*/
public function setQuality($quality)
{
$this->_quality = $quality;
return $this;
}
/**
* @return string
*/
public function getUrl()
{
$media_url = $this->_storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
if ($this->getBaseFile()) {
return $media_url . $this->getResizedFile();
}
return '';
}
/**
* @param string $size
*
* @return $this
*/
public function setSize($size)
{
// determine width and height from string
$width = $height = 0;
if (is_numeric($size)) {
$width = $height = $size;
} elseif (is_array($size)) {
if (1 >= count($size)) {
[$width, $height] = $size;
} else {
$width = $height = array_shift($size);
}
} elseif (is_string($size)) {
[$width, $height] = explode('x', strtolower($size), 2);
}
foreach (['width', 'height'] as $wh) {
${$wh} = (int)${$wh};
if (empty(${$wh})) {
${$wh} = null;
}
}
// set sizes
$this->setWidth($width)->setHeight($height);
return $this;
}
public function removeResized($file)
{
if (!empty($file)) {
$this->init($file);
}
$file = $this->getBaseFile();
if (!empty($file)) {
$new_filename = pathinfo($file);
$new_filename['filename'] = implode('_',
[$new_filename['filename'], '*']) . '.' . $new_filename['extension'];
$pattern = implode('/',
[$this->getDestinationSubdir(), $new_filename['dirname'], $new_filename['filename']]);
$pattern = $this->_mediaDirectory->getAbsolutePath($pattern);
$files = (array)@glob($pattern);
if (!empty($files)) {
foreach ($files as $_file) {
if (file_exists($_file)) {
@unlink($_file);
}
}
}
}
}
/**
* Get image size
*
* @param string $imagePath
*
* @return array
*/
private function getImageSize($imagePath)
{
$imageSize = getimagesize($imagePath);
return $imageSize;
}
}