596 lines
13 KiB
PHP
Executable File
596 lines
13 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* Image helper
|
|
*
|
|
* Copyright © 2023 Olegnax. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
namespace Olegnax\BrandSlider\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 {
|
|
|
|
const DEST_FOLDER = 'bandsresized';
|
|
public $_imageExist;
|
|
protected $_baseFile;
|
|
protected $_resizedFile;
|
|
/**
|
|
* @var AdapterFactory
|
|
*/
|
|
protected $adapterFactory;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $cachePrefix = 'IMG_INFO';
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $_width;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $_height;
|
|
|
|
/**
|
|
* Default quality value (for JPEG images only).
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $_quality = 80;
|
|
|
|
/**
|
|
* @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;
|
|
|
|
/**
|
|
* Store Manager
|
|
*
|
|
* @var StoreManagerInterface
|
|
*/
|
|
private $_storeManager;
|
|
|
|
/**
|
|
* @var WriteInterface
|
|
*/
|
|
protected $_mediaDirectory;
|
|
/**
|
|
* @var Factory
|
|
*/
|
|
private $_imageFactory;
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $attributes;
|
|
|
|
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 (0 < $this->getWidth() && 0 < $this->getHeight() && (bool)$this->getFullPath()) {
|
|
if ($this->_keepAspectRatio && $this->_cropOnly) {
|
|
$this->crop();
|
|
}
|
|
$this->resize();
|
|
} else {
|
|
$this->_resizedFile = $this->_baseFile;
|
|
}
|
|
} else {
|
|
$this->_resizedFile = $this->_baseFile;
|
|
}
|
|
|
|
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 init( $file, $attributes = [] ) {
|
|
$this->_processor = null;
|
|
$this->_resizedFile = null;
|
|
|
|
$this->setBaseFile( $file );
|
|
|
|
$this->attributes = $attributes;
|
|
$this->setImageProperties();
|
|
}
|
|
|
|
/**
|
|
* Retrieve image attribute
|
|
*
|
|
* @param string $name
|
|
* @return string
|
|
*/
|
|
protected function getAttribute( $name ) {
|
|
return $this->attributes[ $name ] ?? null;
|
|
}
|
|
|
|
/**
|
|
* Set image properties
|
|
*
|
|
* @return $this
|
|
*/
|
|
protected function setImageProperties() {
|
|
$this->setDestinationSubdir( self::DEST_FOLDER );
|
|
|
|
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* @param string $dir
|
|
* @return $this
|
|
*/
|
|
public function setDestinationSubdir( $dir ) {
|
|
$this->_destinationSubdir = $dir;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getDestinationSubdir() {
|
|
return $this->_destinationSubdir;
|
|
}
|
|
|
|
/**
|
|
* @param MagentoImage $processor
|
|
* @return $this
|
|
*/
|
|
public function setImageProcessor( $processor ) {
|
|
$this->_processor = $processor;
|
|
return $this;
|
|
}
|
|
|
|
public function crop() {
|
|
if ( $this->getWidth() === null && $this->getHeight() === null ) {
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* @see \Magento\Framework\Image\Adapter\AbstractAdapter
|
|
* @return $this
|
|
*/
|
|
public function resize() {
|
|
if ( $this->getWidth() === null && $this->getHeight() === null ) {
|
|
return $this;
|
|
}
|
|
|
|
$resizedFile = $this->getResizedFile();
|
|
if ( $resizedFile && $this->_fileExists( $resizedFile ) ) {
|
|
return $this;
|
|
}
|
|
|
|
$new_filename = $this->_mediaDirectory->getAbsolutePath( $resizedFile );
|
|
$_processor = $this->getImageProcessor();
|
|
if ( $_processor ) {
|
|
$_processor->resize( $this->_width, $this->_height );
|
|
$_processor->save( $new_filename );
|
|
}
|
|
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getFullPath() {
|
|
$filename = $this->getBaseFile();
|
|
if ( $this->_fileExists( $filename ) ) {
|
|
$filename = $this->_mediaDirectory->getAbsolutePath( $filename );
|
|
|
|
return $filename;
|
|
} else {
|
|
//file_put_contents(BP . '/var/log/oxbrands.log', print_r($filename, true) . "\n", FILE_APPEND);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return MagentoImage
|
|
*/
|
|
public function getImageProcessor() {
|
|
if ( !$this->_processor ) {
|
|
$filename = $this->getFullPath();
|
|
$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 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 ) {
|
|
$this->_baseFile = $file;
|
|
return $this;
|
|
}
|
|
|
|
private function getResizedFile() {
|
|
if ( empty( $this->_resizedFile ) ) {
|
|
$baseFile = $this->getBaseFile();
|
|
if ( !empty( $baseFile ) ) {
|
|
$new_filename = pathinfo( $baseFile );
|
|
if ( is_array( $new_filename ) && !empty( $new_filename ) ) {
|
|
$new_filename[ 'filename' ] = implode( '_', [ $new_filename[ 'filename' ], $this->getWidth(), $this->getHeight() ] ) . '.' . $new_filename[ 'extension' ];
|
|
$this->_resizedFile = implode( '/', [ $this->getDestinationSubdir(), $new_filename[ 'dirname' ], $new_filename[ 'filename' ] ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->_resizedFile;
|
|
}
|
|
|
|
/**
|
|
* 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 ) {
|
|
$path = $this->_mediaDirectory->getAbsolutePath( $filename );
|
|
$this->_imageExist = !empty( $filename ) && file_exists( $path ) && !is_dir( $path );
|
|
return $this->_imageExist;
|
|
}
|
|
|
|
/**
|
|
* @param int $width
|
|
* @return $this
|
|
*/
|
|
public function setWidth( $width ) {
|
|
$this->_width = $width;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getWidth() {
|
|
return $this->_width;
|
|
}
|
|
|
|
/**
|
|
* @param int $height
|
|
* @return $this
|
|
*/
|
|
public function setHeight( $height ) {
|
|
$this->_height = $height;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getHeight() {
|
|
return $this->_height;
|
|
}
|
|
|
|
/**
|
|
* Set image quality, values in percentage from 0 to 100
|
|
*
|
|
* @param int $quality
|
|
* @return $this
|
|
*/
|
|
public function setQuality( $quality ) {
|
|
$this->_quality = $quality;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get image quality
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getQuality() {
|
|
return $this->_quality;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getUrl() {
|
|
return $this->_storeManager->getStore()->getBaseUrl( UrlInterface::URL_TYPE_MEDIA ) . ( $this->getResizedFile() ?: $this->getBaseFile());
|
|
}
|
|
|
|
/**
|
|
* @param bool $keep
|
|
* @return $this
|
|
*/
|
|
public function setKeepAspectRatio( $keep ) {
|
|
$this->_keepAspectRatio = $keep && $keep !== 'false';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param bool $keep
|
|
* @return $this
|
|
*/
|
|
public function setKeepFrame( $keep ) {
|
|
$this->_keepFrame = $keep && $keep !== 'false';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param bool $keep
|
|
* @return $this
|
|
*/
|
|
public function setKeepTransparency( $keep ) {
|
|
$this->_keepTransparency = $keep && $keep !== 'false';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param bool $flag
|
|
* @return $this
|
|
*/
|
|
public function setConstrainOnly( $flag ) {
|
|
$this->_constrainOnly = $flag && $flag !== 'false';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param bool $flag
|
|
* @return $this
|
|
*/
|
|
public function seCropOnly( $flag ) {
|
|
$this->_cropOnly = $flag && $flag !== 'false';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param int[] $rgbArray
|
|
* @return $this
|
|
*/
|
|
public function setBackgroundColor( array $rgbArray ) {
|
|
$this->_backgroundColor = $rgbArray;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
|
|
/**
|
|
* Get image size
|
|
*
|
|
* @param string $imagePath
|
|
* @return array
|
|
*/
|
|
private function getImageSize( $imagePath ) {
|
|
$imageSize = getimagesize( $imagePath );
|
|
return $imageSize;
|
|
}
|
|
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|