AutorÃa | Ultima modificación | Ver Log |
<?php
namespace LeadersLinked\Library;
use LeadersLinked\Model\User;
use LeadersLinked\Model\UserProfile;
use LeadersLinked\Model\Company;
use LeadersLinked\Model\Group;
class Storage
{
const FILE_TYPE_IMAGE = 'image';
const FILE_TYPE_VIDEO = 'video';
const FILE_TYPE_DOCUMENT = 'document';
const TYPE_DEFAULT = 'default';
const TYPE_CHAT = 'chat';
const TYPE_GROUP = 'group';
const TYPE_USER = 'user';
const TYPE_IMAGE = 'image';
const TYPE_JOB = 'job';
const TYPE_MEDIA = 'media';
const TYPE_COMPANY = 'company';
const TYPE_FEED = 'feed';
const TYPE_POST = 'post';
const TYPE_MICROLEARNING_TOPIC = 'topic';
const TYPE_MICROLEARNING_CAPSULE = 'capsule';
const TYPE_MICROLEARNING_SLIDE = 'slide';
const TYPE_JOB_DESCRIPTION = 'jobdesc';
const TYPE_SELF_EVALUATION = 'selfval';
const TYPE_PERFORMANCE_EVALUATION = 'perfeva';
const TYPE_RECRUITMENT_SELECTION = 'recrsel';
const TYPE_PLANNING_OBJECTIVES_AND_GOALS = 'plannig';
const TYPE_MESSAGE = 'message';
const TYPE_SURVEY = 'survey';
const TYPE_NETWORK = 'network';
const TYPE_DAILY_PULSE = 'dailpuls';
const TYPE_ENGAGEMENT_REWARD = 'engarewr';
const TYPE_KNOWLEDGE_AREA = 'knowarea';
const TYPE_MY_COACH = 'mycoach';
const TYPE_HABIT_EMOJI = 'habit-emoji';
const TYPE_HABIT_CONTENT = 'habit-content';
/**
*
* @var\LeadersLinked\Library\Storage
*/
private static $_instance;
/**
*
* @var array
*/
private $config;
/**
*
* @var \Laminas\Db\Adapter\AdapterInterface
*/
private $adapter;
/**
*
* @var string
*/
private $tempPath;
/**
*
* @var string
*/
private $storagePath;
/**
*
* @var array
*/
private $currentFile;
/**
*
* @var array
*/
private $files;
/**
*
* @param array $config
* @param \Laminas\Db\Adapter\AdapterInterface $adapter
*/
private function __construct($config, $adapter)
{
$this->config = $config;
$this->adapter = $adapter;
$this->currentFile = [];
$this->storagePath = 'data' . DIRECTORY_SEPARATOR . 'storage';
if (! file_exists($this->storagePath)) {
mkdir($this->storagePath, 0775, true);
}
$this->tempPath = 'data' . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'tmp';
if (! file_exists($this->tempPath)) {
mkdir($this->tempPath, 0775, true);
}
}
/**
*
* @param array $config
* @param \Laminas\Db\Adapter\AdapterInterface $adapter
* @return \LeadersLinked\Library\Storage
*/
public static function getInstance($config, $adapter)
{
if (self::$_instance == null) {
self::$_instance = new Storage($config, $adapter);
}
return self::$_instance;
}
/**
*
* @return string
*/
public function getFullPathImageDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageUserDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-user.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageUserPofileDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-user-profile.png';
}
/**
*
* @return string
*/
public function getFullPathImageUserCoverDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageCompanyDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-company.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageCompanyCoverDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageGroupDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-group.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageGroupCoverDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
}
/**
*
* @return string
*/
public function getFullPathImageCompanyHeaderPdfDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR . 'company-header.png';
}
/**
*
* @return string
*/
public function getFullPathImageCompanyFooterPdfDefault()
{
return $this->storagePath . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR . 'company-footer.png';
}
/**
*
* @return string
*/
public function getStoagePath()
{
return $this->storagePath;
}
/**
*
* @return string
*/
public function getTempPath()
{
return $this->tempPath;
}
/**
*
* @return array
*/
public function getCurrentFile()
{
return $this->currentFile;
}
/**
*
* @param array $currentFile
*/
public function setCurrentFile($currentFile)
{
$this->currentFile = $currentFile;
}
/**
*
* @param array $filename
*/
public function setCurrentFilename($filename)
{
if (empty($this->files)) {
if (isset($_FILES[$filename]) && empty($_FILES[$filename]['error'])) {
$this->currentFile = $_FILES[$filename];
} else {
$this->currentFile = [];
}
} else {
if (isset($this->files[$filename]) && empty($this->files[$filename]['error'])) {
$this->currentFile = $this->files[$filename];
} else {
$this->currentFile = [];
}
}
return !empty($this->currentFile);
}
/**
*
* @return boolean
*/
public function hasFile()
{
return !empty($this->currentFile);
}
/**
*
* @param array $files
*/
public function setFiles($files)
{
$this->files = $files;
}
/**
*
* @param string $type
* @param string $code
* @param string $filename
* @return string
*/
public function composePathToFilename($type, $code, $filename)
{
$path = $this->getPathByType($type);
$path = $path . DIRECTORY_SEPARATOR . $code;
if (! file_exists($path)) {
mkdir($path, 0775, true);
}
return $path . DIRECTORY_SEPARATOR . $filename;
}
/**
*
* @param string $type
* @param string $code
* @return string
*/
public function composePathToDirectory($type, $code)
{
$path = $this->getPathByType($type);
$path = $path . DIRECTORY_SEPARATOR . $code;
if (! file_exists($path)) {
mkdir($path, 0775, true);
}
return $path;
}
/**
* Private helper to get a presigned URL for an entity's image/cover or its default.
*
* @param string $entityType The type of the entity (e.g., self::TYPE_USER).
* @param string $entityUuid The UUID of the entity.
* @param string|null $imageFilename The filename of the image/cover, if it exists.
* @param string $defaultImageMethodName The name of the method in this class to get the full path to the default image.
* @return string The presigned URL.
*/
private function _getProcessedImageOrCoverUrl($entityType, $entityUuid, $imageFilename, $defaultImageMethodName)
{
if ($imageFilename) {
$remoto = $this->composePathToFilename($entityType, $entityUuid, $imageFilename);
if (file_exists($remoto)) {
return $this->getPresignedUrl($remoto);
}
}
// If imageFilename is null/empty, or the specific file doesn't exist, use the default.
$defaultFullPath = $this->$defaultImageMethodName();
return $this->getPresignedUrl($defaultFullPath);
}
/**
*
* @param User $user
* @return string
*/
public function getUserImage($user)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $user->image, 'getFullPathImageUserDefault');
}
/**
*
* @param User $user
* @return string
*/
public function getUserImageForCodeAndFilename($code, $filename)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $code, $filename, 'getFullPathImageUserDefault');
}
/**
*
* @param User $user
* @param UserProfile $userProfile
* @return string
*/
public function getUserProfileImage($user, $userProfile)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $userProfile->image, 'getFullPathImageUserPofileDefault');
}
/**
*
* @param User $user
* @param UserProfile $userProfile
* @return string
*/
public function getUserProfileCover($user, $userProfile)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $userProfile->cover, 'getFullPathImageUserCoverDefault');
}
/**
*
* @param Company $company
* @return string
*/
public function getCompanyImage($company)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $company->uuid, $company->image, 'getFullPathImageCompanyDefault');
}
/**
*
* @param string $code
* @param string $filename
* @return string
*/
public function getCompanyImageForCodeAndFilename($code, $filename)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $code, $filename, 'getFullPathImageCompanyDefault');
}
/**
*
* @param Company $company
* @return string
*/
public function getCompanyCover($company)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $company->uuid, $company->cover, 'getFullPathImageCompanyCoverDefault');
}
/**
*
* @param Group $group
* @return string
*/
public function getGroupImage($group)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_GROUP, $group->uuid, $group->image, 'getFullPathImageGroupDefault');
}
/**
*
* @param string $code
* @param string $filename
* @return string
*/
public function getGroupImageForCodeAndFilename($code, $filename)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $code, $filename, 'getFullPathImageGroupDefault');
}
/**
*
* @param Group $group
* @return string
*/
public function getGroupCover($group)
{
return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $group->uuid, $group->cover, 'getFullPathImageGroupCoverDefault');
}
/**
*
* @param Group $group
* @return string
*/
public function getGenericImage($path, $code, $filename)
{
$remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
if (file_exists($remoto)) {
return $this->getPresignedUrl($remoto);
}
$remoto = $this->getFullPathImageDefault();
return $this->getPresignedUrl($remoto);
}
/**
*
* @param string $path
* @param string $code,
* @param string $filename
* @return string
*/
public function getGenericFile($path, $code, $filename)
{
$remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
if (file_exists($remoto)) {
if ($code == 'd8e6c5de-52a6-4c28-bdce-4ba2823ba841') {
error_log('getGenericFile = ' . $remoto);
}
return $this->getPresignedUrl($remoto);
}
return;
}
public function getPathDefault()
{
return $this->getPathByType(self::TYPE_DEFAULT);
}
public function getPathChat()
{
return $this->getPathByType(self::TYPE_CHAT);
}
public function getPathGroup()
{
return $this->getPathByType(self::TYPE_GROUP);
}
public function getPathUser()
{
return $this->getPathByType(self::TYPE_USER);
}
public function getPathImage()
{
return $this->getPathByType(self::TYPE_IMAGE);
}
public function getPathJob()
{
return $this->getPathByType(self::TYPE_JOB);
}
public function getPathCompany()
{
return $this->getPathByType(self::TYPE_COMPANY);
}
public function getPathFeed()
{
return $this->getPathByType(self::TYPE_FEED);
}
public function getPathMedia()
{
return $this->getPathByType(self::TYPE_MEDIA);
}
public function getPathPost()
{
return $this->getPathByType(self::TYPE_POST);
}
public function getPathMicrolearningTopic()
{
return $this->getPathByType(self::TYPE_MICROLEARNING_TOPIC);
}
public function getPathMicrolearningCapsule()
{
return $this->getPathByType(self::TYPE_MICROLEARNING_CAPSULE);
}
public function getPathMicrolearningSlide()
{
return $this->getPathByType(self::TYPE_MICROLEARNING_SLIDE);
}
public function getPathJobDescription()
{
return $this->getPathByType(self::TYPE_JOB_DESCRIPTION);
}
public function getPathSelfEvaluation()
{
return $this->getPathByType(self::TYPE_SELF_EVALUATION);
}
public function getPathPerformanceEvaluation()
{
return $this->getPathByType(self::TYPE_PERFORMANCE_EVALUATION);
}
public function getPathRecruitmentSelection()
{
return $this->getPathByType(self::TYPE_RECRUITMENT_SELECTION);
}
public function getPathPlanningObjectivesAndGoals()
{
return $this->getPathByType(self::TYPE_PLANNING_OBJECTIVES_AND_GOALS);
}
public function getPathMessage()
{
return $this->getPathByType(self::TYPE_MESSAGE);
}
public function getPathSurvey()
{
return $this->getPathByType(self::TYPE_SURVEY);
}
public function getPathNetwork()
{
return $this->getPathByType(self::TYPE_NETWORK);
}
public function getPathDailyPulse()
{
return $this->getPathByType(self::TYPE_DAILY_PULSE);
}
public function getPathEngagementReward()
{
return $this->getPathByType(self::TYPE_ENGAGEMENT_REWARD);
}
public function getPathKnowledgeArea()
{
return $this->getPathByType(self::TYPE_KNOWLEDGE_AREA);
}
public function getPathMyCoach()
{
return $this->getPathByType(self::TYPE_MY_COACH);
}
public function getPathHabitEmoji()
{
return $this->getPathByType(self::TYPE_HABIT_EMOJI);
}
public function getPathHabitContent()
{
return $this->getPathByType(self::TYPE_HABIT_CONTENT);
}
public function getPathByType($type)
{
switch ($type) {
case self::TYPE_DEFAULT:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'default';
break;
case self::TYPE_CHAT:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'chat';
break;
case self::TYPE_GROUP:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'group';
break;
case self::TYPE_USER:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'user';
break;
case self::TYPE_IMAGE:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'image';
break;
case self::TYPE_JOB:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'job';
break;
case self::TYPE_COMPANY:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'company';
break;
case self::TYPE_FEED:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'feed';
break;
case self::TYPE_MEDIA:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'media';
break;
case self::TYPE_POST:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'post';
break;
case self::TYPE_MICROLEARNING_TOPIC:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'topic';
break;
case self::TYPE_MICROLEARNING_CAPSULE:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'capsule';
break;
case self::TYPE_MICROLEARNING_SLIDE:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'slide';
break;
case self::TYPE_JOB_DESCRIPTION:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'job-description';
break;
case self::TYPE_SELF_EVALUATION:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'self-evaluation';
break;
case self::TYPE_PERFORMANCE_EVALUATION:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'performance-evaluation';
break;
case self::TYPE_RECRUITMENT_SELECTION:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'recruitment-selection';
break;
case self::TYPE_PLANNING_OBJECTIVES_AND_GOALS:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'planning-objectives-and-goals';
break;
case self::TYPE_MESSAGE:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'message';
break;
case self::TYPE_SURVEY:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'survey';
break;
case self::TYPE_NETWORK:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'network';
break;
case self::TYPE_DAILY_PULSE:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'daily-pulse';
break;
case self::TYPE_ENGAGEMENT_REWARD:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'engagement-reward';
break;
case self::TYPE_KNOWLEDGE_AREA:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'knowledge-area';
break;
case self::TYPE_MY_COACH:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'my-coach';
break;
case self::TYPE_HABIT_EMOJI:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'habit' . DIRECTORY_SEPARATOR . 'emoji';
break;
case self::TYPE_HABIT_CONTENT:
$path = $this->storagePath . DIRECTORY_SEPARATOR . 'habit' . DIRECTORY_SEPARATOR . 'content';
break;
default:
$path = $this->storagePath;
break;
}
if (! file_exists($path)) {
mkdir($path, 0775, true);
}
return $path;
}
/**
*
* @param string $path
* @param string $code
* @param string $filename
* @return string
*/
public function deleteFile($path, $code, $filename)
{
$remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
if (file_exists($remoto)) {
return unlink($remoto);
} else {
return true;
}
}
/**
*
* @param string $type
* @param string $code
* @return boolean
*/
public function deleteDirectory($type, $code)
{
$path = $this->getPathByType($type);
$remoto = $path . DIRECTORY_SEPARATOR . $code;
if (file_exists($remoto)) {
$this->deleteDirectoryRecursive($remoto);
return true;
} else {
return true;
}
}
/**
*
* @param string $dir
*/
private function deleteDirectoryRecursive($dir)
{
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
$s = $dir . DIRECTORY_SEPARATOR . $object;
if (is_dir($s) && ! is_link($s)) {
$this->deleteDirectoryRecursive($s);
} else {
unlink($s);
}
}
}
rmdir($dir);
}
}
/**
*
* @param string $path
* @param string $code
* @param string $local_filename
* @return boolean
*/
public function putFile($source_file, $target_file)
{
return rename($source_file, $target_file);
}
/**
*
* @param string $tempfile
* @param string $path
* @param string $code
* @param string $filename
* @return boolean
*/
public function moveUploadedFile($source_file, $target_file)
{
return move_uploaded_file($source_file, $target_file);
}
/**
*
* @param string $tempfile
* @param string $path
* @param string $code
* @param string $filename
* @return boolean
*/
public function copyFile($source_file, $target_file)
{
return copy($source_file, $target_file);
}
/**
*
* @param string $url
* @return string
*/
public function getPresignedUrl($url)
{
$code = hash('sha256', $url);
$storageFileMapper = \LeadersLinked\Mapper\StorageFileMapper::getInstance($this->adapter);
$storageFile = $storageFileMapper->fetchOneByCode($code);
if (! $storageFile) {
$storageFile = new \LeadersLinked\Model\StorageFile();
$storageFile->code = $code;
$storageFile->path = $url;
$storageFile->salt = \LeadersLinked\Library\Functions::generatePassword(8);
$storageFileMapper->insert($storageFile);
}
$url = 'https://' . $_SERVER['SERVER_NAME'] . '/storage/' . $code;
return $url;
}
/**
*
* @return @return void|string
*/
public function getFilenamePNG()
{
if ($this->currentFile) {
$filename = $this->normalizeStringFilename($this->currentFile['name']);
$path_parts = pathinfo($filename);
return $path_parts['filename'] . '.png';
} else {
return;
}
}
/**
*
* @return @return void|string
*/
public function getTmpFilename()
{
if ($this->currentFile) {
return $this->currentFile['tmp_name'];
} else {
return;
}
}
/**
*
* @return @return void|string
*/
public function getFilename()
{
if ($this->currentFile) {
return $this->normalizeStringFilename($this->currentFile['name']);
} else {
return;
}
}
/**
*
* @return void|string
*/
public function getFileType()
{
if ($this->currentFile) {
$tmp_name = $this->currentFile['tmp_name'];
$mime_type = mime_content_type($tmp_name);
if ($mime_type == 'image/jpg' || $mime_type == 'image/jpeg' || $mime_type == 'image/png') {
return self::FILE_TYPE_IMAGE;
} else if ($mime_type == 'video/quicktime' || $mime_type == 'video/webm' || $mime_type == 'video/mpeg' || $mime_type == 'video/mpg' || $mime_type == 'video/mp4') {
return self::FILE_TYPE_VIDEO;
} else if ($mime_type == 'application/pdf') {
return self::FILE_TYPE_DOCUMENT;
} else {
return;
}
} else {
return;
}
}
/**
*
* @return void|string
*/
public function getExtension()
{
if ($this->currentFile) {
$path_parts = pathinfo($this->currentFile['name']);
$ext = $path_parts['extension'];
return $ext;
} else {
return;
}
}
/**
* Creates a new GD image resource with transparency settings for PNG.
* @param int $width The width of the new image.
* @param int $height The height of the new image.
* @return \GdImage|false The image resource or false on failure.
*/
private function _createImageCanvas($width, $height)
{
$new_image = imageCreateTrueColor($width, $height);
if ($new_image === false) {
error_log("_createImageCanvas: imageCreateTrueColor failed for dimensions {$width}x{$height}.");
return false;
}
imageAlphaBlending($new_image, False);
imageSaveAlpha($new_image, True);
$transparent = imageColorAllocateAlpha($new_image, 0, 0, 0, 127);
if ($transparent === false) {
error_log("_createImageCanvas: imageColorAllocateAlpha failed.");
imagedestroy($new_image);
return false;
}
imagefill($new_image, 0, 0, $transparent);
return $new_image;
}
/**
* Saves a GD image resource as PNG, unlinks source, and cleans up image resource.
* @param \GdImage $imageResource The GD image resource to save.
* @param string $targetFilename The path to save the PNG file to.
* @param string $sourceFilenameToUnlink The path to the source file to unlink.
* @return bool True on success, false on failure.
*/
private function _savePngAndCleanup($imageResource, $targetFilename, $sourceFilenameToUnlink)
{
$save_success = imagepng($imageResource, $targetFilename);
imagedestroy($imageResource); // Clean up the image resource
if ($save_success) {
if ($sourceFilenameToUnlink && file_exists($sourceFilenameToUnlink)) {
unlink($sourceFilenameToUnlink);
}
return true;
} else {
error_log("_savePngAndCleanup: imagepng failed to save image to {$targetFilename}.");
return false;
}
}
/**
*
* @param string $source
* @param string $target_filename
* @param number $target_width
* @param number $target_height
* @return boolean
*/
public function uploadImageResize($source_filename, $target_filename, $target_width, $target_height)
{
try {
$data = file_get_contents($source_filename);
$img = imagecreatefromstring($data);
if ($img) {
list($source_width, $source_height) = getimagesize($source_filename);
$width_ratio = $target_width / $source_width;
$height_ratio = $target_height / $source_height;
if ($width_ratio > $height_ratio) {
$resized_width = $target_width;
$resized_height = $source_height * $width_ratio;
} else {
$resized_height = $target_height;
$resized_width = $source_width * $height_ratio;
}
$resized_width = round($resized_width);
$resized_height = round($resized_height);
$new_image = $this->_createImageCanvas($target_width, $target_height);
if ($new_image === false) {
imagedestroy($img);
unlink($source_filename);
return false;
}
imageCopyResampled($new_image, $img, 0, 0, 0, 0, $resized_width, $resized_height, $source_width, $source_height);
imagedestroy($img); // Source image resource can be destroyed after resampling
return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
}
unlink($source_filename);
return false;
} catch (\Throwable $e) {
error_log($e->getTraceAsString());
if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
imagedestroy($img);
}
if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
imagedestroy($new_image);
}
if (isset($source_filename) && file_exists($source_filename)) {
unlink($source_filename);
}
return false;
}
}
/**
*
* @param string $source
* @param string $target_filename
* @param number $target_width
* @param number $target_height
* @return boolean
*/
public function uploadImageCrop($source_filename, $target_filename, $target_width, $target_height)
{
try {
$data = file_get_contents($source_filename);
$img = imagecreatefromstring($data);
if ($img) {
list($source_width, $source_height) = getimagesize($source_filename);
$width_ratio = $target_width / $source_width;
$height_ratio = $target_height / $source_height;
if ($width_ratio > $height_ratio) {
$resized_width = $target_width;
$resized_height = $source_height * $width_ratio;
} else {
$resized_height = $target_height;
$resized_width = $source_width * $height_ratio;
}
$resized_width = round($resized_width);
$resized_height = round($resized_height);
$offset_width = round(($target_width - $resized_width) / 2);
$offset_height = round(($target_height - $resized_height) / 2);
$new_image = $this->_createImageCanvas($target_width, $target_height);
if ($new_image === false) {
imagedestroy($img);
unlink($source_filename);
return false;
}
imageCopyResampled($new_image, $img, $offset_width, $offset_height, 0, 0, $resized_width, $resized_height, $source_width, $source_height);
imagedestroy($img);
return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
}
unlink($source_filename);
return false;
} catch (\Throwable $e) {
error_log($e->getTraceAsString());
if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
imagedestroy($img);
}
if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
imagedestroy($new_image);
}
if (isset($source_filename) && file_exists($source_filename)) {
unlink($source_filename);
}
return false;
}
}
/**
*
* @param string $source
* @param string $target_filename
* @return boolean
*/
public function uploadImageWithOutChangeSize($source_filename, $target_filename)
{
try {
$data = file_get_contents($source_filename);
$img = imagecreatefromstring($data);
if ($img) {
list($source_width, $source_height) = getimagesize($source_filename);
$new_image = $this->_createImageCanvas($source_width, $source_height);
if ($new_image === false) {
imagedestroy($img);
unlink($source_filename);
return false;
}
imageCopyResampled($new_image, $img, 0, 0, 0, 0, $source_width, $source_height, $source_width, $source_height);
imagedestroy($img);
return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
}
unlink($source_filename);
return false;
} catch (\Throwable $e) {
error_log($e->getTraceAsString());
if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
imagedestroy($img);
}
if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
imagedestroy($new_image);
}
if (isset($source_filename) && file_exists($source_filename)) {
unlink($source_filename);
}
return false;
}
}
public static function extractPosterFromVideo($source_filename, $target_filename)
{
try {
$cmd = "/usr/bin/ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width,duration $source_filename";
$response = trim(shell_exec($cmd));
$source_duration = 0;
$lines = explode("\n", $response);
foreach ($lines as $line) {
$line = trim(strtolower($line));
if (strpos($line, 'duration') !== false) {
$values = explode('=', $line);
$source_duration = intval(str_replace($values[1], '#', ''), 10);
}
}
if ($source_duration == 0) {
$second_extract = '00:00:02';
} else {
if ($source_duration > 10) {
$second_extract = '00:00:10';
} else {
$second_extract = '00:00:02';
}
}
$cmd = "/usr/bin/ffmpeg -y -i $source_filename -pix_fmt yuvj422p -an -ss $second_extract -f mjpeg -t 1 -r 1 -y $target_filename";
exec($cmd);
return true;
} catch (\Throwable $e) {
error_log($e->getTraceAsString());
return false;
}
}
/**
*
* @param string $str
* @return string
*/
public function normalizeStringFilename($str = '')
{
$basename = substr($str, 0, strrpos($str, '.'));
$basename = str_replace('.', '-', $basename);
$extension = substr($str, strrpos($str, '.'));
$str = $basename . $extension;
$str = strip_tags($str);
$str = preg_replace('/[\r\n\t ]+/', ' ', $str);
$str = preg_replace('/[\#\"\*\/\:\<\>\?\'\|\,]+/', ' ', $str);
$str = strtolower($str);
$str = html_entity_decode($str, ENT_QUOTES, "utf-8");
$str = htmlentities($str, ENT_QUOTES, "utf-8");
$str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
$str = str_replace(' ', '-', $str);
$str = rawurlencode($str);
$str = str_replace('%', '-', $str);
$str = str_replace([
'-----',
'----',
'---',
'--'
], '-', $str);
return trim(strtolower($str));
}
}