<?php
/*******************************************************************************
* FRESHIZER -> WP Image Resizer Script
* =============================================================================
*
* @license GNU version 2
* @author freshace
* @version 1.5
* @link http://github.com/boobslover/freshizer
/*******************************************************************************
* SETTINGS, PLEASE CHANGE ONLE THESE 3 CONSTANTS
******************************************************************************/
// NOTE
// ====
// please notice, that the time is in SECONDS. There are not allowed math
// operations in the definition. So instead of writing:
// = 60(sec) * 60(min) * 24(hr) * 7(days); you have to write:
// = 604800; // seconds in 7 days
// CACHE TIME
// ==========
// When the new (cached) file is older than this time, script automatically
// checks, if the old file has been changed. If not, then ve serve cached file
// again. If yes, cached file is deleted and resized again.
define('CACHE_TIME', 604800);
// CACHE DELETE FILES AFTER
// ========================
// Hard delete files ( not only compare if the original file has been changed,
// but hardly delete from caching folder ), every X seconds. Please fill a large
// number, because cached files runs much more speedely
define('CACHE_DELETE_FILES_AFTER',10000000);
// CACHE DELETE FILES - check every X hits
// =======================================
// How often do we check if there are files which should be hard deleted ?
// Optimal is approx 400 - 500 hits
define('CACHE_DELETE_FILES_check_every_x_hits',150);
class blFile {
CONST POINTER_END = 'pend';
private $_handle = null;
private $_fileSize = null;
private $_path = null;
private $_writeBuffer = '';
/*----------------------------------------------------------------------------*/
/* FUNCTIONS PUBLIC
/*----------------------------------------------------------------------------*/
public function __construct( $handle, $path ) {
$this->_setHandle( $handle );
$this->_setPath( $path );
}
public function readAll() {
if( $this->getFileSize() > 0 )
return (fread( $this->getHandle(), $this->getFileSize() ));
else
return null;
}
public function read( $size ) {
if( $this->getFileSize() > 0 )
return fread( $this->getHandle(), $size );
else
return null;
}
public function readAllAndClose() {
$fileContent = $this->readAll();
$this->closeFile();
return $fileContent;
}
/**
* @param string $content
* @return blFile
*/
public function write( $content ) {
fwrite( $this->getHandle(), ( $content ) );
return $this;
}
public function writeBuffered( $content ) {
$this->_setWriteBuffer( $content );
return $this;
}
/*public function __destruct() {
var_dump($this);
if( $this->_writeBuffer != '' ) {
$this->write( $this->_writeBuffer ) ;
}
$this->closeFile();
}*/
/**
* @return blFile
*/
public function truncate() {
ftruncate( $this->getHandle(), 0);
$this->pointerStart();
return $this;
}
public function closeFile() {
if( $this->getHandle() !== null ) {
fclose( $this->getHandle() );
$this->_setHandle(null);
}
}
/**
* @return blFile
*/
public function pointerStart() {
$this->_movePointer( 0 );
return $this;
}
/**
* @return blFile
*/
public function pointerEnd() {
$this->_movePointer( self::POINTER_END );
return $this;
}
/**
* @param int $where
* @return blFile
*/
public function pointerTo( $where ) {
return $this->_movePointer( $where );
return $this;
}
/*----------------------------------------------------------------------------*/
/* FUNCTIONS PRIVATE
/*----------------------------------------------------------------------------*/
private function _movePointer( $where ) {
if( $where == self::POINTER_END ) {
fseek( $this->getHandle(), 0, SEEK_END);
} else {
fseek( $this->getHandle(), $where, SEEK_SET);
}
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _setWriteBuffer( $content ) {
$this->_writeBuffer = $content;
}
private function _getWriteBuffer() {
return $this->_writeBuffer;
}
public function getHandle() {
return $this->_handle;
}
private function _setHandle( $handle ) {
$this->_handle = $handle;
}
public function getPath() {
return $this->_path;
}
private function _setPath( $path ) {
$this->_path = $path;
}
public function getFileSize() {
if( $this->_fileSize == null ) {
$this->_fileSize = filesize( $this->getPath() );
}
return $this->_fileSize;
}
}
class blFileSystem {
private $_errors = array();
/*----------------------------------------------------------------------------*/
/* FUNCTIONS PUBLIC
/*----------------------------------------------------------------------------*/
/**
* Trying to open file. If neccessary, creates dir and file automatically
*
* @param string $path
* @param bool $writing
* @return blFile
*/
public function openFile( $path, $writing = false ) {
if( file_exists( $path ) ) {
$mode = ( $writing ) ? 'r+' : 'r';
} else {
$mode = ( $writing ) ? 'c+' : 'c';
}
return $this->_openFile( $path, $mode );
}
/**
* Open file, if exists, truncate
* @param string $path
* @param bool $writing
* @return blFile
*/
public function createFile( $path, $writing = false ) {
$mode = ( $writing ) ? 'c+' : 'c';
return $this->_openFile( $path, $mode );
}
public function deleteFile( $path ) {}
public function createDir( $path ) {
if( mkdir( $path, 0777, true ) === false ) {
$this->_addError( 'Unable to create DIR :'. $path );
}
}
public function saveImage( $image, $path ) {
$pinfo = pathinfo( $path );
$ext = $pinfo['extension'];
$return = null;
switch( $ext ) {
case 'jpg':
$return = imagejpeg($image, $path, 90 );
break;
case 'jpeg':
$return = imagejpeg($image, $path, 90 );
break;
case 'png':
$return = imagepng( $image, $path, 0 );
break;
case 'gif':
$return = imagegif( $image, $path );
break;
}
return $return;
}
/*----------------------------------------------------------------------------*/
/* FUNCTIONS PRIVATE
/*----------------------------------------------------------------------------*/
private function _openFile( $path, $mode ) {
$pathInfo = pathinfo( $path );
$dirname = $pathInfo['dirname'];
$file = null;
if( !is_dir( $dirname ) ) {
$this->createDir( $dirname );
}
$fileHandler = fopen( $path, $mode);
$file = new blFile( $fileHandler, $path);
return $file;
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
public function getErorrs() {
return $this->_errors;
}
private function _addError( $error ) {
$this->_errors[] = $error;
}
}
interface blIConnection {
public function getContent( $url );
}
class blConnectionAdapteur implements blIConnection {
/**
* @var blIConnection
*/
private $_connectionMethod = null;
/*----------------------------------------------------------------------------*/
/* PUBLIC FUNCTIONS
/*----------------------------------------------------------------------------*/
public function getContent( $url ) {
return $this->_getConnectionMethod()->getContent($url);
}
/*----------------------------------------------------------------------------*/
/* PRIVATE FUNCTIONS
/*----------------------------------------------------------------------------*/
private function _createProperConnection() {
if( ini_get('allow_url_fopen') ) {
$this->_setConnectionMethod( new blConnectionFopen() );
} else if( function_exists( 'curl_init') ) {
$this->_setConnectionMethod( new blConnectionCurl() );
}
}
/*----------------------------------------------------------------------------*/
/* GETTERS AND SETTERS
/*----------------------------------------------------------------------------*/
private function _setConnectionMethod( blIConnection $connectionMethod ) {
$this->_connectionMethod = $connectionMethod;
}
/**
* @return blIConnection
*/
private function _getConnectionMethod() {
if( $this->_connectionMethod == null ) {
$this->_createProperConnection();
}
return $this->_connectionMethod;
}
}
class blConnectionCurl implements blIConnection {
public function getContent( $url ) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}
class blConnectionFopen implements blIConnection {
public function getContent( $url ) {
$handle = fopen( $url, 'rb' );
$fileContent = '';
if( $handle !== false ) {
while (!feof($handle)) {
$fileContent .= fread($handle, 8192);
}
fclose( $handle );
}
return $fileContent;
}
}
class blDownloader {
/**
* @var blIConnection
*/
private $_connectionMethod = null;
public function getContent( $url ) {
return $this->_getConnectionMethod()->getContent($url);
}
/**
*
* @param blIConnection $connectionMethod
*/
private function _setConnectionMethod( blIConnection $connectionMethod ) {
$this->_connectionMethod = $connectionMethod;
}
/**
* @return blIConnection
*/
private function _getConnectionMethod() {
if( $this->_connectionMethod == null ) {
$this->_setConnectionMethod( new blConnectionAdapteur() );
}
return $this->_connectionMethod;
}
}
class blImgCache {
CONST CACHE_FILENAME = 'img_caching_info.frs';
/**
* @var blFileSystem
*/
private $_fileSystem = null;
/**
* @var blFile
*/
private $_cacheFile = null;
private $_cacheFileUnparsed = null;
private $_cacheFileParsed = null;
private $_cacheFileDir = null;
public function __construct( blFileSystem $fileSystem, $cacheFileDir ) {
$this->_setFileSystem($fileSystem);
$this->_setCacheFileDir($cacheFileDir . self::CACHE_FILENAME );
$this->_loadCacheFile();
$this->_unparseCacheFile();
}
public function addCachedFileRemote( $urlNew, $pathNew, $urlOld ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
if( $this->_cacheFileUnparsed == null ) {
$this->_cacheFileUnparsed = new stdClass();
}
if( !isset( $cacheFileUnparsed->remoteDataHolder[ $urlOld ] ) ) {
$cachedFile = new stdClass();
$cachedFile->urlNew = $urlNew;
$cachedFile->pathNew = $pathNew;
$cachedFile->urlOld = $urlOld;
$cachedFile->timestamp = time();
$cacheFileUnparsed->remoteDataHolder[ $cachedFile->urlOld] = $cachedFile;
}
}
public function addCachedFile( $urlNew, $urlOld, $pathNew, $pathOld, $remote = false ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
if( $this->_cacheFileUnparsed == null ) {
$this->_cacheFileUnparsed = new stdClass();
}
if( !isset( $cacheFileUnparsed->dataHolder[ $urlNew ] ) ) {
$cachedFile = new stdClass();
$cachedFile->urlNew = $urlNew;
$cachedFile->urlOld = $urlOld;
$cachedFile->pathNew = $pathNew;
$cachedFile->pathOld = $pathOld;
$cachedFile->remote = $remote;
$cachedFile->timestamp = time();
$cacheFileUnparsed->dataHolder[ $cachedFile->urlNew] = $cachedFile;
}
}
public function deleteCacheInfo( $urlNew ) {
unset( $this->_getCacheFileUnparsed()->dataHolder[ $urlNew ] );
}
public function deleteRemoteCacheInfo( $url ) {
unset( $this->_getCacheFileUnparsed()->remoteDataHolder[ $url ] );
}
public function getCacheInfo( $urlNew ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
if( isset( $cacheFileUnparsed->dataHolder[ $urlNew ] ) ) {
$cachedImageInfo = $cacheFileUnparsed->dataHolder[ $urlNew ];
$cachedImageInfo->valid = $this->_checkExpiration($cachedImageInfo);
return $cacheFileUnparsed->dataHolder[ $urlNew ];
} else {
return null;
}
}
public function touchCachedFile( $urlNew ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
$cacheFileUnparsed->dataHolder[ $urlNew ]->valid = true;
$cacheFileUnparsed->dataHolder[ $urlNew ]->timestamp = time();
}
public function getRemoteCacheInfo( $urlOld ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
if( isset( $cacheFileUnparsed->remoteDataHolder[ $urlOld ] ) ) {
$cachedImageInfo = $cacheFileUnparsed->remoteDataHolder[ $urlOld ];
$cachedImageInfo->valid = $this->_checkExpiration($cachedImageInfo);
return $cacheFileUnparsed->remoteDataHolder[ $urlOld ];
} else {
return null;
}
}
private function _checkExpiration( stdClass $cachedImageInfo ) {
$currentTimestamp = time();
$oldTimestamp = $cachedImageInfo->timestamp;
if( ( $oldTimestamp + CACHE_TIME ) < $currentTimestamp ) {
return false;
} else {
return true;
}
}
/*public function deleteCacheInfo( $urlNew ) {
$cacheFileUnparsed = $this->_getCacheFileUnparsed();
unset( $cacheFileUnparsed->dataHolder[ $urlNew ] );
}*/
public function __destruct() {
$this->saveCacheFile();
}
public function saveCacheFile() {
$this->_parseCacheFile();
$this->_saveCacheFile();
}
private function _parseCacheFile() {
$cacheFileParsed = serialize( $this->_getCacheFileUnparsed() );
$this->_setCacheFileParsed( $cacheFileParsed );
}
private function _saveCacheFile() {
if( $this->_getCacheFile()->getHandle() == null ) return ;
$this->_getCacheFile()
->truncate()
->write( $this->_getCacheFileParsed() )
->closeFile();
}
private function _loadCacheFile() {
$cacheFile = $this->_getFileSystem()->openFile( $this->_getCacheFileDir(), true);
$this->_setCacheFile( $cacheFile );
$this->_setCacheFileParsed( $cacheFile->readAll() );
}
private function _unparseCacheFile() {
if( $this->_getCacheFileParsed() != '') {
$cacheFileContentUnparsed = unserialize( $this->_getCacheFileParsed() );
$cacheFileContentUnparsed->hitsAfterLastDelete++;
$this->_setCacheFileUnparsed( $cacheFileContentUnparsed );
} else {
$cacheFileContentUnparsed = new stdClass();
$cacheFileContentUnparsed->hitsAfterLastDelete = 1;
$this->_setCacheFileUnparsed( $cacheFileContentUnparsed );
}
if( $cacheFileContentUnparsed->hitsAfterLastDelete >= CACHE_DELETE_FILES_check_every_x_hits ) {
$this->_hardDeleteCache();
}
}
private function _hardDeleteCache() {
//var_dump(CACHE_DELETE_FILES_check_every_x_hits);
$unsetArray = array();
if( !empty( $this->_getCacheFileUnparsed()->dataHolder ) ) {
foreach( $this->_getCacheFileUnparsed()->dataHolder as $url => $fileData ) {
//pathNew, timestamp
if( ( $fileData->timestamp + CACHE_DELETE_FILES_AFTER ) <= time() ) {
$unsetArray[] = $url;
unlink( $fileData->pathNew);
}
}
}
foreach( $unsetArray as $oneUrl ) {
unset ($this->_getCacheFileUnparsed()->dataHolder[ $oneUrl ] );
}
$unsetArray = array();
if( !empty( $this->_getCacheFileUnparsed()->remoteDataHolder ) ) {
foreach( $this->_getCacheFileUnparsed()->remoteDataHolder as $url => $fileData ) {
//pathNew, timestamp
if( ( $fileData->timestamp + CACHE_DELETE_FILES_AFTER ) <= time() ) {
$unsetArray[] = $url;
unlink( $fileData->pathNew);
}
}
}
foreach( $unsetArray as $oneUrl ) {
unset ($this->_getCacheFileUnparsed()->remoteData[ $oneUrl ] );
}
$this->_getCacheFileUnparsed()->hitsAfterLastDelete = 0;
}
private function _setCacheFileParsed( $cacheFileParsed ) {
$this->_cacheFileParsed = $cacheFileParsed;
}
private function _getCacheFileParsed() {
return $this->_cacheFileParsed;
}
private function _setCacheFileUnparsed( $cacheFileUnparsed ) {
$this->_cacheFileUnparsed = $cacheFileUnparsed;
}
private function _getCacheFileUnparsed() {
return $this->_cacheFileUnparsed;
}
private function _setCacheFileDir( $cacheFileDir) {
$this->_cacheFileDir = $cacheFileDir;
}
private function _getCacheFileDir() {
return $this->_cacheFileDir;
}
private function _setCacheFile( blFile $cacheFile ) {
$this->_cacheFile = $cacheFile;
}
/**
* @return blFile
*/
private function _getCacheFile() {
return $this->_cacheFile;
}
private function _setFileSystem( blFileSystem $fileSystem ) {
$this->_fileSystem = $fileSystem;
}
/**
*
* @return blFileSystem
*/
private function _getFileSystem() {
return $this->_fileSystem;
}
}
class blImgDownloader {
/**
* @var blFileSystem
*/
private $_fileSystem = null;
/**
* @var blInputStreamAdapteour
*/
private $_inputStream = null;
public function __construct( blFileSystem $fileSystem, blInputStreamAdapteour $inputStreamAdapter ) {
$this->_setFileSystem( $fileSystem );
$this->_setInputStream( $inputStreamAdapter );
}
public function downloadImage( $originalPath, $newPath ) {
$img = $this->_getInputStream()->open( $originalPath )->readAll();
if( $img != null ) {
$this->_getFileSystem()->createFile( $newPath, true)->write( $img )->closeFile();
}
}
private function _setInputStream( blInputStreamAdapteour $inputStreamAdapter ) {
$this->_inputStream = $inputStreamAdapter;
}
/**
* @return blInputStreamAdapteour
*/
private function _getInputStream() {
return $this->_inputStream;
}
private function _setFileSystem( blFileSystem $fileSystem ) {
$this->_fileSystem = $fileSystem;
}
/**
* @return blFileSystem
*/
private function _getFileSystem() {
return $this->_fileSystem;
}
}
interface blIInputStream {
public function open( $path );
public function readAll();
}
class blInputStreamFile implements blIInputStream {
/**
* @var blFileSystem
*/
private $_fileSystem = null;
/**
* @var blFile
*/
private $_openedFile = null;
public function __construct() {
}
/**
* (non-PHPdoc)
* @see blIInputStream::open()
*/
public function open( $path ) {
$file = $this->_getFileSystem()->openFile($path);
$this->_setFile( $file );
return $this;
}
public function readAll() {
return $this->_getFile()->readAllAndClose();
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _setFileSystem( blFileSystem $fileSystem ) {
$this->_fileSystem = $fileSystem;
}
/**
* @return blFileSystem
*/
private function _getFileSystem() {
if( $this->_fileSystem == null ) {
$this->_setFileSystem( new blFileSystem() );
}
return $this->_fileSystem;
}
private function _setFile( blFile $file ) {
$this->_openedFile = $file;
}
/**
* @return blFile
*/
private function _getFile() {
return $this->_openedFile;
}
}
class blInputStreamHttp implements blIInputStream {
/**
* @var blDownloader
*/
private $_downloader = null;
private $_pageContent = '';
public function open( $path ) {
$content = $this->_getDownloader()->getContent( $path );
$this->_setPageContent( $content );
}
public function readAll() {
return $this->_getPageContent();
}
/**
* @return blDownloader
*/
private function _getDownloader() {
if( $this->_downloader == null ) {
$this->_downloader = new blDownloader();
}
return $this->_downloader;
}
private function _setPageContent( $pageContent ) {
$this->_pageContent = $pageContent;
}
private function _getPageContent() {
return $this->_pageContent;
}
}
class blInputStreamAdapteour implements blIInputStream {
/**
*
* @var blIInputStream
*/
private $_inputStream = null;
/*----------------------------------------------------------------------------*/
/* PUBLIC FUNCTIONS
/*----------------------------------------------------------------------------*/
public function open( $path ) {
$this->_createInputStream( $path );
$this->_getInputStream()->open($path);
return $this;
}
public function readAll() {
return $this->_getInputStream()->readAll();
}
/*----------------------------------------------------------------------------*/
/* PRIVATE FUNCTIONS
/*----------------------------------------------------------------------------*/
private function _createInputStream( $path ) {
if( strpos( $path, 'http://') !== false ) {
$this->_setInputStream( new blInputStreamHttp() );
} else {
$this->_setInputStream( new blInputStreamFile() );
}
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _setInputStream( blIInputStream $inputStream ) {
$this->_inputStream = $inputStream;
}
private function _getInputStream() {
return $this->_inputStream;
}
}
class fImgOneData {
public $path = null;
public $url = null;
public $filename = null;
public $width = null;
public $height = null;
public $timestamp = null;
public $crop = null;
}
class fImgData {
/**
*
* @var fImgOneData
*/
public $new = null;
/**
*
* @var fImgOneData
*/
public $old = null;
public $remote = false;
public $ready = false;
public function __construct() {
$this->new = new fImgOneData();
$this->old = new fImgOneData();
}
}
class fImgDeliverer {
/**
* @var blFileSystem
*/
private $_fileSystem = null;
/**
*
* @var blInputStreamAdapteour
*/
private $_inputStream = null;
/**
* @var blImgCache
*/
private $_imgCache = null;
/**
*
* @var fImgPathPredictor
*/
private $_imgPredictor = null;
/**
*
* @var blImgDownloader
*/
private $_imgDownloader = null;
private $_uploadDir = null;
private $_uploadUrl = null;
/**
*
* @var fImgNamer
*/
private $_imgNamer = null;
public function __construct( blFileSystem $fileSystem, $inputStream, blImgCache $imgCache, $uploadDir, $uploadUrl ) {
$this->_setFileSystem( $fileSystem );
$this->_setInputStream( $inputStream );
$this->_setImgCache( $imgCache);
$this->_setUploadDir( $uploadDir );
$this->_setUploadUrl( $uploadUrl );
}
/**
*
* @param fImgData $imgData
* @return fImgData
*/
public function deliveryImage( fImgData $imgData ) {
$result = $this->_deliveryFromCache( $imgData );
//$result = false;
if( $result === false )
$result = $this->_deliveryFromLocal( $imgData );
if( $result === false )
$result = $this->_deliveryFromRemote( $imgData );
return $result;
}
private function _deliveryFromCache( fImgData $imgData ) {
$cacheInfo = $this->_getImgCache()->getCacheInfo( $imgData->new->url );
if( $cacheInfo == null ) return false;
$imgData->new->path = $this->_getUploadDirPath( $imgData->new->filename );
$cacheValidity = $this->_checkCacheValidity( $imgData, $cacheInfo );
if( $cacheValidity === false ) return false;
$imgData->ready = true;
return $imgData;
}
private function _checkCacheValidity( fImgData $imgData, $cacheInfo ) {
if( $cacheInfo->valid == true ) return true;
if( !file_exists( $cacheInfo->pathOld) ) {
$this->_getImgCache()->deleteCacheInfo( $imgData->new->url );
$this->_getFileSystem()->deleteFile( $imgData->new->path );
return false;
}
$newTS = $cacheInfo->timestamp;
$oldTS = filemtime( $cacheInfo->pathOld );
if( $newTS > $oldTS ) {
$this->_getImgCache()->touchCachedFile( $imgData->new->url );
return true;
} else {
$this->_getImgCache()->deleteCacheInfo( $imgData->new->url );
$this->_getFileSystem()->deleteFile( $imgData->new->path );
return false;
}
}
private function _deliveryFromLocal( fImgData $imgData ) {
$path = $this->_getImgPredictor()->predictPath( $imgData->old->url );
if( $path != null ) {
$imgData->old->path = $path;
if ($this->_doesntHasAlphaLayer($path) && false ) {
$imgData->new->filename = $this->_getImgNamer()->renameToJpg( $imgData->new->filename );
$imgData->new->url = $this->_getImgNamer()->renameToJpg( $imgData->new->url );
}
$imgData->new->path = $this->_getUploadDirPath( $imgData->new->filename );
$imgData->ready = false;
return $imgData;
} else {
return false;
}
}
private function _doesntHasAlphaLayer( $path ) {
if( file_exists( $path )) {
$pathInfo = pathInfo($path);
if( $pathInfo['extension'] != 'png') {
return false;
}
$firstChars = $this->_getFileSystem()->openFile($path)->read(26);//->pointerTo(25)->read(1);
//var_dump($firstChars);
$char = $firstChars[25];
$pngType = (ord($char));
// var_dump($pngType);
}
if( $pngType == 6 ) {
return false;
} else {
return true;
}
}
private function _deliveryFromRemote( fImgData $imgData ) {
$remoteFilename = $this->_getImgNamer()->getRemoteImageName( $imgData->old->url );
$remotePath = $this->_getUploadDirPath('remote/' . $remoteFilename);
$remoteUrl = $this->_getUploadUrlPath('remote/' . $remoteFilename);
$remoteFileCacheInfo = $this->_getImgCache()
->getRemoteCacheInfo($imgData->old->url);
//->getCacheInfo( $remotePath);
if( $remoteFileCacheInfo != null && $remoteCacheInfo->valid == false ) {
$remoteFileCacheInfo = null;
$this->_getImgCache()->deleteRemoteCacheInfo( $remoteUrl );
$this->_getFileSystem()->deleteFile( $remotePath );
}
if( $remoteFileCacheInfo == null ) {
$this->_getImgDownloader()->downloadImage($imgData->old->url, $remotePath );
if( file_exists( $remotePath) ) {
$this->_getImgCache()->addCachedFileRemote($remoteUrl, $remotePath, $imgData->old->url);
//$this->_getImgCache()->addCachedFile($urlNew, $urlOld, $pathNew, $pathOld, $remote)
}
}
$imgData->new->path = $this->_getUploadDirPath( $imgData->new->filename );
$imgData->old->url = $remoteUrl;
$imgData->old->path = $remotePath;
$imgData->ready = false;
$imgData->remote = true;
return $imgData;
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _getUploadDirPath( $path ) {
return $this->_getUploadDir() . $path;
}
private function _getUploadUrlPath ( $path ) {
return $this->_getUploadUrl() .'/'. $path;
}
private function _getUploadUrl() {
return $this->_uploadUrl;
}
private function _setUploadUrl( $uploadUrl ) {
$this->_uploadUrl = $uploadUrl;
}
private function _getImgDownloader() {
if( $this->_imgDownloader == null ) {
$this->_imgDownloader = new blImgDownloader( $this->_getFileSystem(), $this->_getInputStream() );
}
return $this->_imgDownloader;
}
private function _getImgNamer() {
if( $this->_imgNamer == null ) {
$this->_imgNamer = new fImgNamer();
}
return $this->_imgNamer;
}
private function _setUploadDir( $uploadDir ) {
$this->_uploadDir = $uploadDir;
}
private function _getUploadDir() {
return $this->_uploadDir;
}
/**
* @return fImgPathPredictor
*/
private function _getImgPredictor() {
if( $this->_imgPredictor == null ) {
$this->_imgPredictor = new fImgPathPredictor();
}
return $this->_imgPredictor;
}
private function _setImgCache( blImgCache $imgCache ) {
$this->_imgCache = $imgCache;
}
/**
*
* @return blImgCache
*/
private function _getImgCache(){
return $this->_imgCache;
}
private function _setFileSystem( blFileSystem $fileSystem ) {
$this->_fileSystem = $fileSystem;
}
/**
* @return blFileSystem
*/
private function _getFileSystem() {
return $this->_fileSystem;
}
private function _setInputStream( blInputStreamAdapteour $inputStream ) {
$this->_inputStream = $inputStream;
}
/**
* @return blInputStreamAdapteour
*/
private function _getInputStream() {
return $this->_inputStream;
}
}
class fImgNamer {
private $_defaultUrl = null;
private $_temporaryPathInfo = null;
public function __construct( $defaultUrl = null ) {
$this->_setDefaultUrl( $defaultUrl );
}
public function getNewImageName( $oldUrl, $width, $height = false, $crop = false, $remote = false) {
$newUrl = '';
$partRemote = ( $remote ) ? 'remote/' : '';
$partWidth = '-'.$width;
$partHeight = ( $height ) ? '-'.$height : '';
$partCrop = ( $crop ) ? '-c' : '';
//$newUrl .= $this->_getDefaultUrl() .'/';
$newUrl .= $partRemote;
$newUrl .= $this->_getUrlHash( $oldUrl ) . '_' ;
$newUrl .= $this->_getImgName( $oldUrl );
$newUrl .= $partWidth;
$newUrl .= $partHeight;
$newUrl .= $partCrop;
$newUrl .= $this->_getImgExtension();
return $newUrl;
}
public function renameToJpg( $path ) {
$pathInfo = ( pathinfo($path));
//var_dump( $pathInfo['dirname'] == '.');
( $pathInfo['dirname'] == '.' ) ? $dirname = '' : $dirname = $pathInfo['dirname'] .'/';
$toReturn =$dirname . $pathInfo['filename'] . '.jpg';
//var_dump($toReturn);
return $toReturn;
}
public function getNewImageUrl( $oldUrl, $width, $height = false, $crop = false, $remote = false ) {
/**
* http://defaulturl(freshizer)/[remote]/$oldUrlHash_imgFilename-width[-height][-c(rop)].ext
*/
$newUrl = '';
$partRemote = ( $remote ) ? 'remote/' : '';
$partWidth = '-'.$width;
$partHeight = ( $height ) ? '-'.$height : '';
$partCrop = ( $crop ) ? '-c' : '';
$newUrl .= $this->_getDefaultUrl() .'/';
$newUrl .= $partRemote;
$newUrl .= $this->_getUrlHash( $oldUrl ) . '_' ;
$newUrl .= $this->_getImgName( $oldUrl );
$newUrl .= $partWidth;
$newUrl .= $partHeight;
$newUrl .= $partCrop;
$newUrl .= $this->_getImgExtension();
return $newUrl;
}
public function getRemoteImageName( $url ) {
$pathInfo = pathinfo( $url );
$newName = '';
$newName .= $this->_getUrlHash( $url );
$newName .= '-'.$pathInfo['filename'].'.'.$pathInfo['extension'];
return $newName;
}
private function _getImgExtension() {
$pathInfo = $this->_getTemporaryPathInfo();
return '.'.$pathInfo['extension'];
}
private function _getImgName( $oldUrl ) {
$pathInfo = pathinfo( $oldUrl );
$this->_setTemporaryPathInfo( $pathInfo );
return $pathInfo['filename'];
}
private function _setTemporaryPathInfo( $pathInfo ) {
$this->_temporaryPathInfo = $pathInfo;
}
private function _getTemporaryPathInfo() {
return $this->_temporaryPathInfo;
}
private function _getUrlHash( $url ) {
return md5($url);
}
private function _setDefaultUrl( $defaultUrl ) {
$this->_defaultUrl = $defaultUrl;
}
private function _getDefaultUrl() {
return $this->_defaultUrl;
}
}
interface fIImgPathPredictor {
public function predictPath( $url );
/*private function _predictionJunction();
private function _predictUploads();
private function _predictThemes();
private function _predictPlugins();*/
}
class fAImgPathPredictor implements fIImgPathPredictor {
public function predictPath( $url ) {}
protected function _predictUploads() {}
protected function _predictThemes() {}
protected function _predictPlugins() {}
}
class fImgPathPredictor {
/**
*
* @var fIImgPathPredictor
*/
private $_predictor = null;
public function predictPath( $url ) {
return $this->_getPredictor()->predictPath( $url );
}
private function _initializePredictor() {
global $blog_id;
if( is_multisite() && $blog_id != 1) {
$this->_setPredictor( new fImgPathPredictor_Multisite() );
} else {
$this->_setPredictor( new fImgPathPredictor_Single() );
}
}
private function _setPredictor( fIImgPathPredictor $predictor) {
$this->_predictor = $predictor;
}
/**
* @return fIImgPathPredictor
*/
private function _getPredictor() {
if( $this->_predictor == null ) {
$this->_initializePredictor();
}
return $this->_predictor;
}
}
class fImgPathPredictor_Multisite extends fAImgPathPredictor implements fIImgPathPredictor {
private $_imgUrl = null;
private $_predictedPath = null;
public function predictPath( $url ) {
$this->_setImgUrl( $url );
$this->_predictionJunction();
return $this->_getPredictedPath();
}
protected function _predictionJunction() {
//echo $this->_getImgUrl().'xxxx';
//return;
$uploadDir = wp_upload_dir();
if( strpos( $this->_getImgUrl(), $uploadDir['baseurl']) !== false ) {
$this->_predictUploads();
} else if ( strpos( $this->_getImgUrl(), 'wp-content/themes') !== false ) {
$this->_predictThemes();
} else if ( strpos( $this->_getImgUrl(), 'wp-content/themes') !== false ) {
$this->_predictPlugins();
}
}
protected function _predictUploads() {
$uploadDir = wp_upload_dir();
$uploadSubpath = str_replace( $uploadDir['baseurl'],'', $this->_getImgUrl());
$newRelPath = $uploadDir['basedir'].$uploadSubpath;
if( file_exists( $newRelPath) ) {
$this->_setPredictedPath( $newRelPath );
}
}
protected function _predictThemes() {
$splitedUrl = explode('themes/', $this->_getImgUrl() ); //explode() $this->_getImgUrl();
$splitedPath = explode('themes/', get_template_directory() );
$newRelPath = $splitedPath[0].'themes/'.$splitedUrl[1];
if( file_exists( $newRelPath )) {
$this->_setPredictedPath( $newRelPath );
}
}
protected function _predictPlugins() {
$imgPluginDirSplitted = explode('wp-content/plugins', $this->_getImgUrl() );
$imgAfterPluginDir = $imgPluginDirSplited[1];
$pluginDir = WP_PLUGIN_DIR;
$newRelPath = $pluginDir . $imgAfterPluginDir;
if( file_exists( $newRelPath ) ) {
$this->_setPredictedPath( $newRelPath );
}
}
private function _getPredictedPath() {
return $this->_predictedPath;
}
private function _setPredictedPath( $predictedPath ) {
$this->_predictedPath = $predictedPath;
}
private function _setImgUrl( $imgUrl ) {
$this->_imgUrl = $imgUrl;
}
private function _getImgUrl() {
return $this->_imgUrl;
}
}
class fImgPathPredictor_Single extends fAImgPathPredictor implements fIImgPathPredictor {
private $_imgUrl = null;
private $_predictedPath = null;
public function predictPath( $url ) {
$this->_setImgUrl( $url );
$this->_predictionJunction();
return $this->_getPredictedPath();
}
protected function _predictionJunction() {
if( strpos( $this->_getImgUrl(), 'wp-content/uploads') !== false ) {
$this->_predictUploads();
} else if ( strpos( $this->_getImgUrl(), 'wp-content/themes') !== false ) {
$this->_predictThemes();
} else if ( strpos( $this->_getImgUrl(), 'wp-content/themes') !== false ) {
$this->_predictPlugins();
}
}
protected function _predictUploads() {
$imgUploadDirSplited = explode('wp-content/uploads', $this->_getImgUrl() );
$imgAfterUploadDir = $imgUploadDirSplited[1];
$wpUploadDir = wp_upload_dir();
$baseDir = $wpUploadDir['basedir'];
$newRelPath = $baseDir . $imgAfterUploadDir;
if( file_exists( $newRelPath) ) {
$this->_setPredictedPath( $newRelPath );
}
}
protected function _predictThemes() {
$imgThemeDirSplited = explode('wp-content/themes', $this->_getImgUrl() );
$imgAfterThemeDir = $imgThemeDirSplited[1];
$currentThemeDirSplited = explode( 'wp-content/themes', get_template_directory());
$currentThemeFolder = $currentThemeDirSplited[0];
$newRelPath = $currentThemeFolder . 'wp-content/themes' . $imgAfterThemeDir;
if( file_exists( $newRelPath )) {
$this->_setPredictedPath( $newRelPath );
}
}
protected function _predictPlugins() {
$imgPluginDirSplitted = explode('wp-content/plugins', $this->_getImgUrl() );
$imgAfterPluginDir = $imgPluginDirSplited[1];
$pluginDir = WP_PLUGIN_DIR;
$newRelPath = $pluginDir . $imgAfterPluginDir;
if( file_exists( $newRelPath ) ) {
$this->_setPredictedPath( $newRelPath );
}
}
private function _getPredictedPath() {
return $this->_predictedPath;
}
private function _setPredictedPath( $predictedPath ) {
$this->_predictedPath = $predictedPath;
}
private function _setImgUrl( $imgUrl ) {
$this->_imgUrl = $imgUrl;
}
private function _getImgUrl() {
return $this->_imgUrl;
}
}
class fImgResizer {
/**
*
* @var blFileSystem
*/
private $_fileSystem = null;
/**
* @var fImgResizerCalculator
*/
private $_imgResizerCalculator = null;
private $_imgHasAlfaChannel = null;
public function __construct( blFileSystem $fileSystem ) {
$this->_setFileSystem($fileSystem);
}
public function resize( fImgData $imgData ) {// stdClass $pathInfo, stdClass $imgInfo ) {
//var_dump($imgData);
$imageOld = $this->_openImage( $imgData->old->path );
$orig = $this->_getImgDimensions( $imgData->old->path );
$newDimensions = $this->_getImgResizerCalculator()->calculateNewDimensions( $orig->width,
$orig->height,
$imgData->new->width,
$imgData->new->height,
$imgData->new->crop );
$imageNew = $this->_createImage( $newDimensions['dst']['w'],$newDimensions['dst']['h']);
imagecopyresampled($imageNew, $imageOld, $newDimensions['dst']['x'],
$newDimensions['dst']['y'],
$newDimensions['src']['x'],
$newDimensions['src']['y'],
$newDimensions['dst']['w'],
$newDimensions['dst']['h'],
$newDimensions['src']['w'],
$newDimensions['src']['h']);
if(function_exists('imageantialias') ) {
imageantialias( $imageNew, true );
}
$pathInfo = pathinfo($imgData->old->path);
if ( $pathInfo['extension'] == 'png' && function_exists('imageistruecolor') && !imageistruecolor( $imageOld ) ) {
imagetruecolortopalette( $imageNew, false, imagecolorstotal( $imageOld ) );
}
$this->_getFileSystem()->saveImage( $imageNew, $imgData->new->path );
imagedestroy($imageOld);
imagedestroy($imageNew);
$this->_imgHasAlfaChannel = null;
$dimToReturn = array();
}
private function _openImage( $path ) {
$imageString = $this->_getFileSystem()->openFile( $path )->readAllAndClose();
$pathInfo = pathinfo($path);
if( $pathInfo['extension'] == 'png' && ord($imageString[25]) == 6 )
$this->_imgHasAlfaChannel = true;
//return (ord(@file_get_contents($fn, NULL, NULL, 25, 1)) == 6);
@ini_set( 'memory_limit', '256M' );
$image = imagecreatefromstring( $imageString );
return $image;
}
private function _getImgDimensions( $path ) {
$dim = getimagesize( $path );
$result = new stdClass();
$result->width = $dim[0];
$result->height = $dim[1];
return $result;
}
private function _createImage ($width, $height) {
$img = imagecreatetruecolor($width, $height);
if ( is_resource($img) && $this->_imgHasAlfaChannel && function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
imagealphablending($img, false);
imagesavealpha($img, true);
}
return $img;
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _getImgResizerCalculator() {
if( $this->_imgResizerCalculator == null ) {
$this->_imgResizerCalculator = new fImgResizerCalculator();
}
return $this->_imgResizerCalculator;
}
/**
* @return blFileSystem
*/
private function _getFileSystem() {
return $this->_fileSystem;
}
private function _setFileSystem( $fileSystem ) {
$this->_fileSystem = $fileSystem;
}
}
class fImgResizerCalculator {
public function calculateNewDimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
if ( $crop ) {
// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
$aspect_ratio = $orig_w / $orig_h;
$new_w =$dest_w;// min($dest_w, $orig_w);
$new_h =$dest_h;// min($dest_h, $orig_h);
if ( !$new_w ) {
$new_w = intval($new_h * $aspect_ratio);
}
if ( !$new_h ) {
$new_h = intval($new_w / $aspect_ratio);
}
$size_ratio = max($new_w / $orig_w, $new_h / $orig_h);
$crop_w = round($new_w / $size_ratio);
$crop_h = round($new_h / $size_ratio);
$s_x = floor( ($orig_w - $crop_w) / 2 );
$s_y = floor( ($orig_h - $crop_h) / 2 );
} else {
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
$crop_w = $orig_w;
$crop_h = $orig_h;
$s_x = 0;
$s_y = 0;
list( $new_w, $new_h ) = $this->constrainNewDimensions( $orig_w, $orig_h, $dest_w, $dest_h );
}
$to_return = array();
$to_return['src']['x'] = (int)$s_x;
$to_return['src']['y'] = (int)$s_y;
$to_return['src']['w'] = (int)$crop_w;
$to_return['src']['h'] = (int)$crop_h;
$to_return['dst']['x'] = 0;
$to_return['dst']['y'] = 0;
$to_return['dst']['w'] = (int)$new_w;
$to_return['dst']['h'] = (int)$new_h;
return $to_return;
}
/**
* This function has been take over from wordpress core. It calculate the best proportion to uncropped image
*/
public function constrainNewDimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) {
if ( !$max_width and !$max_height )
return array( $current_width, $current_height );
$width_ratio = $height_ratio = 1.0;
$did_width = $did_height = false;
if ( $max_width > 0 && $current_width > 0 )
{
$width_ratio = $max_width / $current_width;
$did_width = true;
}
if ( $max_height > 0 && $current_height > 0 )
{
$height_ratio = $max_height / $current_height;
$did_height = true;
}
// Calculate the larger/smaller ratios
$smaller_ratio = min( $width_ratio, $height_ratio );
$larger_ratio = max( $width_ratio, $height_ratio );
if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
// The larger ratio is too big. It would result in an overflow.
$ratio = $smaller_ratio;
else
// The larger ratio fits, and is likely to be a more "snug" fit.
$ratio = $larger_ratio;
//echo $current_width;
if( $max_width > $current_width && $max_height == 0 ) {
$ratio = $larger_ratio;
}
$w = intval( $current_width * $ratio );
$h = intval( $current_height * $ratio );
// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
// Thus we look for dimensions that are one pixel shy of the max value and bump them up
if ( $did_width && $w == $max_width - 1 )
$w = $max_width; // Round it up
if ( $did_height && $h == $max_height - 1 )
$h = $max_height; // Round it up
return array( $w, $h );
}
}
class fImg {
/**
* @var fImg
*/
private static $_instance = null;
/**
* @var fImgNamer
*/
private $_imgNamer = null;
/**
* @var blFileSystem
*/
private $_fileSystem = null;
/**
* @var blImgCache
*/
private $_imgCache = null;
/**
* @var fImgDeliverer
*/
private $_imgDeliverer = null;
/**
* @var blInputStreamAdapteour
*/
private $_inputStream = null;
/**
* @var fImgResizer
*/
private $_imgResizer = null;
private $_defaultUrl = null;
private $_defaultDir = null;
/*----------------------------------------------------------------------------*/
/* PUBLIC FUNCTIONS
/*----------------------------------------------------------------------------*/
public function __construct() {
$this->_createDefaultUrlAndDir();
$this->_setImgCache( new blImgCache( $this->_getFileSystem(), $this->_getDefaultDir() ) );
$this->_setImgDeliverer( new fImgDeliverer( $this->_getFileSystem(), $this->_getInputStream(), $this->_getImgCache(), $this->_getDefaultDir(), $this->_getDefaultUrl() ) );
$this->_setImgResizer( new fImgResizer( $this->_getFileSystem() ) );
}
public function getInstance() {
if( self::$_instance == null ) {
self::$_instance = new fImg();
}
return self::$_instance;
}
public static function ResizeC( $url, $width, $height = false, $crop = false, $returnImgSize = false ) {
$width = (int)$width;
$height = (int)$height;
return self::getInstance()->_resize($url, $width, $height, $crop, $returnImgSize);
}
public static function resize( $url, $width, $height = false, $crop = false, $returnImgSize = false ) {
$width = (int)$width;
$height = (int)$height;
return self::getInstance()->_resize($url, $width, $height, $crop, $returnImgSize = false);
}
public static function getImgSize( $url ) {
return self::getInstance()->_getImgSize( $url );
}
private function _getImgSize( $url ) {
$imgData = $this->_getImgData($url, 0, false, false);
$imgData = $this->_getImgDeliverer()->deliveryImage($imgData);
return $imgData;
}
private function _resize( $url, $width, $height = false, $crop = false, $returnImgSize = false ) {
if( empty($url) ) return null;
$imgData = $this->_getImgData($url, $width, $height, $crop);
$imgData = $this->_getImgDeliverer()->deliveryImage( $imgData );
if( $imgData == false ) {
echo 'Image :'.$url.' cannot be opened';
return false;
}
if( $imgData->ready == false ) {
$this->_getImgResizer()->resize( $imgData );
$this->_getImgCache()
->addCachedFile( $imgData->new->url, $imgData->old->url, $imgData->new->path, $imgData->old->path, $imgData->remote);
}
if( $returnImgSize ) {
$size = getimagesize($imgData->new->path);
$toReturn = array();
$toReturn['width'] = $size[0];
$toReturn['height'] = $size[1];
$toReturn['url'] = $imgData->new->url;
return $toReturn;
} else {
return $imgData->new->url;
}
}
/*----------------------------------------------------------------------------*/
/* PRIVATE FUNCTIONS
/*----------------------------------------------------------------------------*/
/**
* @return fImgData
*/
private function _getImgData( $url, $width, $height, $crop ) {
$imgData = $this->_getImageInfoAsClass($url, $width, $height, $crop);
$imgData->new->url = $this->_getImgNamer()->getNewImageUrl( $url, $width, $height, $crop);
$imgData->new->filename = $this->_getImgNamer()->getNewImageName($url, $width, $height, $crop);
return $imgData;
}
/**
*
* @return fImgData
*/
private function _getImageInfoAsClass( $url, $width, $height,$crop) {
$imgData = new fImgData();
$imgData->old->url = $url;
$imgData->new->width = (int)$width;
$imgData->new->height = (int)$height;
$imgData->new->crop = $crop;
return $imgData;
}
private function _createDefaultUrlAndDir() {
$wpUploadDir = wp_upload_dir();
$this->_setDefaultUrl( $wpUploadDir['baseurl'].'/freshizer');
$this->_setDefaultDir( $wpUploadDir['basedir'].'/freshizer/');
}
/*----------------------------------------------------------------------------*/
/* SETTERS AND GETTERS
/*----------------------------------------------------------------------------*/
private function _setImgResizer( fImgResizer $imgResizer ) {
$this->_imgResizer = $imgResizer;
}
/**
* @return fImgResizer
*/
private function _getImgResizer() {
return $this->_imgResizer;
}
private function _setImgDeliverer( fImgDeliverer $imgDeliverer ) {
$this->_imgDeliverer = $imgDeliverer;
}
/**
* @return fImgDeliverer
*/
private function _getImgDeliverer() {
return $this->_imgDeliverer;
}
private function _setInputStream( blInputStreamAdapteour $inputStream ) {
$this->_inputStream = $inputStream;
}
/**
*
* @return blInputStreamAdapteour
*/
private function _getInputStream() {
if( $this->_inputStream == null ) {
$this->_inputStream = new blInputStreamAdapteour() ;
}
return $this->_inputStream;
}
private function _setDefaultUrl( $defaultUrl ) {
$this->_defaultUrl = $defaultUrl;
}
private function _getDefaultUrl() {
return $this->_defaultUrl;
}
private function _getImgNamer() {
if( $this->_imgNamer == null ) {
$this->_imgNamer = new fImgNamer($this->_getDefaultUrl());
}
return $this->_imgNamer;
}
private function _getImgCache() {
return $this->_imgCache;
}
private function _setImgCache( blImgCache $imgCache ) {
$this->_imgCache = $imgCache;
}
private function _getFileSystem() {
if( $this->_fileSystem == null ) {
$this->_fileSystem = new blFileSystem();
}
return $this->_fileSystem;
}
private function _setDefaultDir( $defaultDir) {
$this->_defaultDir = $defaultDir;
}
private function _getDefaultDir() {
return $this->_defaultDir;
}
public static function DeleteCache() {
}
}