Created
November 5, 2015 15:20
-
-
Save Thijzer/6fb74b6539e2a2b2edb9 to your computer and use it in GitHub Desktop.
ForkCMS Image library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* This file is part of Fork CMS. | |
* | |
* For the full copyright and license information, please view the license | |
* file that was distributed with this source code. | |
*/ | |
namespace Common; | |
use Common\Uri; | |
use Backend\Core\Engine\Exception; | |
use Backend\Core\Engine\Model as BackendModel; | |
use Backend\Core\Engine\FormImage as BackendFormImage; | |
use Backend\Core\Engine\Language as BL; | |
use Symfony\Component\Filesystem\Filesystem; | |
use Symfony\Component\Finder\Finder; | |
use Symfony\Component\HttpFoundation\File\File; | |
/** | |
* This is an Image Store Class to simplify Image handling | |
* | |
* @author <thijs@wijs.be> | |
*/ | |
class Image | |
{ | |
/** | |
* @var array | |
*/ | |
private $sizes; | |
/** | |
* @var boolean | |
*/ | |
private $isGeneratedFilename = false; | |
private $isValidated = false; | |
/** | |
* @var string | |
*/ | |
private $imagePath; | |
private $sourcePath; | |
private $currentFilename; | |
private $extension = null; | |
/** | |
* @var Filesystem | |
*/ | |
private $fs; | |
/** | |
* @var Finder | |
*/ | |
private $finder; | |
/** | |
* @var BackendFormImage | |
*/ | |
private $image; | |
/** | |
* Constructor | |
* | |
* @param array $settings required | |
* @param string $currentFilename | |
*/ | |
public function __construct(array $settings, $currentFilename = null) | |
{ | |
// create folders if needed | |
$this->fs = new Filesystem(); | |
$this->finder = new Finder(); | |
// setup Settings | |
$this->settings['required'] = true; | |
$this->settings['check_dimensions'] = false; | |
$this->settings['store_path'] = ''; | |
$this->settings['sources'] = array('source'); | |
$this->settings['max_width'] = 0; | |
$this->settings['max_height'] = 0; | |
$this->settings['mimetypes'] = array( | |
'jpg' => 'image/jpg', | |
'jpeg' => 'image/jpeg', | |
'png' => 'image/png', | |
'gif' => 'image/gif', | |
); | |
$this->settings['filesize'] = null; | |
$this->settings = array_merge($this->settings, $settings); | |
$this->settings['extensions'] = array_keys($this->settings['mimetypes']); | |
// size and dimensions | |
if (!is_bool($this->settings['required']) && empty($settings['store_path'])) { | |
new Exception('minimail settings "required" & "store_path" are required'); | |
} | |
$this->imagePath = FRONTEND_FILES_PATH; | |
$this->imagePath .= '/'.strtolower($this->settings['store_path']); | |
// setup your sources | |
$this->sourcePath = $this->imagePath . '/source/'; | |
$this->sizes = $this->getDimensions($this->imagePath); | |
if (count($this->sizes) === 0) { | |
$this->sizes = array($this->sourcePath); | |
} | |
// set the correct extension and current Filename | |
$this->currentFilename = $currentFilename; | |
$this->extension = $this->setExtension($currentFilename); | |
} | |
/** | |
* Validate your Image by Reference | |
* | |
* @param BackendFormImage | |
*/ | |
public function validate(&$image) | |
{ | |
if (empty($this->currentFilename) && $this->settings['required']) { | |
$image->isFilled(BL::err('FieldIsRequired')); | |
} | |
// validate the image | |
if ($image->isFilled()) { | |
// image extension | |
$image->isAllowedExtension( | |
$this->extensions, | |
BL::err('JPGGIFAndPNGOnly') | |
); | |
// Mime Validation | |
$image->isAllowedMimeType( | |
$this->getMimetypes(), | |
BL::err('JPGGIFAndPNGOnly') | |
); | |
// Minimum Dimensions | |
$this->hasMinimumDimensions( | |
$this->settings['width'], | |
$this->settings['height'] | |
); | |
$this->extension = $image->getExtension(); | |
} | |
// set some properties | |
if (!$image->getErrors()) { | |
$this->isValidated = true; | |
$this->image = $image; | |
} | |
} | |
/** | |
* Store your image | |
* | |
* @param string new filename | |
* | |
* @return string the set filename | |
*/ | |
public function save($newFilename = '') | |
{ | |
// sane validation checker | |
if ($this->isValidated === false) { | |
return ''; | |
} | |
// filename | |
$newFilename = $this->getCorrectFilename( | |
$newFilename, | |
$this->image->isFilled() | |
); | |
// default file action | |
if ($this->image->isFilled()) { | |
// init dirs | |
$this->initDirectories(); | |
// remove the old | |
$this->deletePrevious(); | |
// upload the image & generate thumbnails | |
$this->image->generateThumbnails($this->imagePath, $newFilename); | |
return $newFilename; | |
} | |
// no image but we can still rename | |
$this->rename($newFilename); | |
// only change the name if there is a difference | |
return $newFilename; | |
} | |
/** | |
* Delete Previous file | |
*/ | |
public function deletePrevious() | |
{ | |
if (!empty($this->currentFilename)) { | |
$this->fs->remove($this->sourcePath.$this->currentFilename); | |
$this->deleteThumbnails($this->currentFilename); | |
} | |
} | |
/** Is the File Validated */ | |
public function isValidated() | |
{ | |
return $this->isValidated; | |
} | |
/** | |
* manages the filename | |
* | |
* @param string $filename | |
* @param bool $isFilled Required | |
* @return string filename | |
*/ | |
private function getCorrectFilename($filename, $isFilled = false) | |
{ | |
if ($isFilled && $this->currentFilename.$filename === '') { | |
$filename = $this->generateNewFilename(); | |
return $filename; | |
} | |
$filename = (empty($filename)) ? | |
$this->currentFilename : | |
Uri::getUrl($filename).'.'.$this->extension; | |
return $filename; | |
} | |
/** | |
* Delete Thumbnails | |
* | |
* @param string $thumbnail | |
*/ | |
private function deleteThumbnails($thumbnail = '') | |
{ | |
// if there is no image provided we can't do anything | |
if ($thumbnail === '') { | |
return; | |
} | |
foreach ($this->sources as $directory) { | |
$fileName = $directory.'/'.$thumbnail; | |
if (is_file($fileName)) { | |
$this->fs->remove($fileName); | |
} | |
} | |
} | |
/** | |
* Set Extension | |
* | |
* @param string path | |
* @return string current filename | |
*/ | |
private function setExtension($currentFilename) | |
{ | |
if (!empty($currentFilename)) { | |
$path = pathinfo($currentFilename); | |
if (isset($path['extension'])) { | |
return $path['extension']; | |
} | |
} | |
} | |
/** | |
* Get Directories list | |
* | |
* @param string path | |
* @return array source directories | |
*/ | |
private function getDimensions($path) | |
{ | |
foreach ($this->finder->directories()->in($path) as $directory) { | |
$dimensions = null; | |
$path = $directory->getRealPath(); | |
$directories[] = $path; | |
$dimensions = explode('x', strtolower($path)); | |
// store the heighest available resolution | |
if ($this->settings['check_dimensions'] === true && | |
$dimensions !== null && | |
$this->settings['max_width'] < $dimensions[0] && | |
$this->settings['max_height'] < $dimensions[1] | |
) { | |
$this->settings['max_width'] = $dimensions[0]; | |
$this->settings['max_height'] = $dimensions[1]; | |
} | |
} | |
return $directories; | |
} | |
/** | |
* Get Mimetypes | |
* | |
* @return array mimetypes | |
*/ | |
private function getMimetypes() | |
{ | |
return array_values($this->settings['mimetypes']); | |
} | |
/** Init the Image Directories */ | |
private function initDirectories() | |
{ | |
foreach ($this->sizes as $source) { | |
if (!$this->fs->exists($source)) { | |
$this->fs->mkdir($source); | |
if (!$this->fs->exists($source.'/.gitignore')) { | |
$this->fs->dumpfile($source.'/.gitignore', "*\n!.gitignore"); | |
} | |
} | |
} | |
} | |
/** | |
* Generate New Filename | |
* | |
* @return string filename | |
*/ | |
private function generateNewFilename() | |
{ | |
$this->isGeneratedFilename = true; | |
return uniqid().'.'.$this->extension; | |
} | |
/** | |
* Rename | |
* | |
* @param string new | |
*/ | |
private function rename($new) | |
{ | |
$old = $this->currentFilename; | |
if (!empty($old) && $new !== $old) { | |
// loop over folders | |
foreach ($this->sizes as $source) { | |
// move the old file to the new name | |
$this->fs->rename($source.'/'.$old, $source.'/'.$new); | |
} | |
} | |
} | |
/** | |
* Filesize Checker | |
* | |
* @param $largestSize string | |
* @param $size string | |
*/ | |
public function isFilesize($filesize = null, $size = 'kb') | |
{ | |
if ($filesize !== null && is_numeric($filesize)) { | |
$this->image->isFilesize($filesize, $size, null, BL::getError('IncorrectFilesize')); | |
} | |
} | |
/** | |
* Dimensions Checker | |
* | |
* @param $width string | |
* @param $height string | |
*/ | |
private function hasMinimumDimensions() | |
{ | |
if ($this->settings['check_dimensions'] === true && $this->image->getTempFileName()) { | |
$this->image->hasMinimumDimensions( | |
$this->settings['max_width'], | |
$this->settings['max_height'], | |
BL::getError('FileDimensionsToLow') | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment