239 lines
8.5 KiB
PHP
239 lines
8.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Traits;
|
|
|
|
use App\Models\Format;
|
|
use App\Models\Media;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
trait MediaTools
|
|
{
|
|
public function getFileSize($file_path)
|
|
{
|
|
return $this->fixIntegerOverflow(filesize($file_path));
|
|
}
|
|
|
|
/**
|
|
* Create thumbnail image for a Media
|
|
*
|
|
* @param Media $media
|
|
* @return void
|
|
* @throws \ImagickException On errors.
|
|
*/
|
|
public function createThumb(Media $media)
|
|
{
|
|
/** @var \Illuminate\Support\Collection<\App\Models\Format> $formats */
|
|
$formats = optional($media->sujet)->formats ?? collect();
|
|
$mediaPath = public_path("/{$media->folder}{$media->uid}.{$media->extension}");
|
|
$im = new \Imagick($mediaPath);
|
|
$im->setImageBackgroundColor('#ffffff');
|
|
$im->setImageAlphaChannel(\Imagick::ALPHACHANNEL_REMOVE);
|
|
$im->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
|
|
$im->stripImage();
|
|
if (in_array($media->extension, array("pdf", "ai", "psd"))) {
|
|
$im->setIteratorIndex(0);
|
|
}
|
|
|
|
foreach ($formats as $format) {
|
|
$fp = public_path("/{$media->folder}{$media->uid}_{$format->libelle}.{$format->extension}");
|
|
|
|
$targetWidth = \floatval($format->largeur);
|
|
if (\floatval($format->hauteur) == 0) {
|
|
$targetHeight = \floatval(floor(($media->hauteur * $format->largeur) / $media->largeur));
|
|
} else {
|
|
$targetHeight = \floatval($format->hauteur);
|
|
}
|
|
|
|
$im->setImageFormat($format->extension);
|
|
if ($media->largeur >= $targetWidth || $media->hauteur >= $targetHeight) {
|
|
$im->thumbnailImage($targetWidth, $targetHeight, true);
|
|
}
|
|
$im->writeImage($fp);
|
|
}
|
|
$im->destroy();
|
|
unset($im);
|
|
}
|
|
|
|
/**
|
|
* Create Sys thumbnail image for a Media.
|
|
*
|
|
* @param \App\Models\Media $media
|
|
* @return void
|
|
* @throws \ImagickException On errors.
|
|
*/
|
|
public function createSysThumb(Media $media)
|
|
{
|
|
$mediaPath = public_path("/{$media->folder}{$media->uid}.{$media->extension}");
|
|
$im = new \Imagick();
|
|
$im->readImage($mediaPath);
|
|
|
|
if (in_array($media->extension, array("pdf", "ai", "psd"))) {
|
|
$extension = "png";
|
|
$im->setIteratorIndex(0);
|
|
} else {
|
|
/** @var string */
|
|
$extension = $media->extension;
|
|
}
|
|
|
|
/*
|
|
Handle CMJN - DOESN'T WORK
|
|
if ($im->getImageColorspace() === \Imagick::COLORSPACE_CMYK){
|
|
$im->transformImageColorspace(\Imagick::COLORSPACE_RGB);
|
|
}
|
|
*/
|
|
|
|
// * create preview
|
|
/** @var \App\Models\Format $format */
|
|
$format = Format::withoutGlobalScope('App\Scopes\SystemScope')
|
|
->where('libelle', '=', 'preview')->firstOrFail();
|
|
$fp = public_path("/{$media->folder}{$media->uid}_preview.{$extension}");
|
|
if ($media->extension == "gif") {
|
|
if ($media->largeur >= $format->largeur || $media->hauteur >= $format->hauteur || $media->largeur == "") {
|
|
$im = $im->coalesceImages();
|
|
foreach ($im as $frame) {
|
|
$frame->thumbnailImage($format->largeur, $format->hauteur);
|
|
$frame->setImagePage($format->largeur, $format->hauteur, 0, 0);
|
|
}
|
|
$im = $im->deconstructImages();
|
|
}
|
|
$im->writeImages($fp, true);
|
|
} else {
|
|
if ($media->largeur >= $format->largeur || $media->hauteur >= $format->hauteur || $media->largeur == "") {
|
|
$im->thumbnailImage($format->largeur, $format->hauteur, true);
|
|
}
|
|
$im->writeImage($fp);
|
|
}
|
|
|
|
|
|
// * create thumb
|
|
/** @var \App\Models\Format $format */
|
|
$format = Format::withoutGlobalScope('App\Scopes\SystemScope')
|
|
->where('libelle', '=', 'thumb')->firstOrFail();
|
|
if ($extension != "png") {
|
|
$im->setImageBackgroundColor('#ffffff');
|
|
$im->setImageAlphaChannel(\Imagick::ALPHACHANNEL_REMOVE);
|
|
$im->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
|
|
$im->stripImage();
|
|
}
|
|
$fp = public_path("/{$media->folder}{$media->uid}_thumb.{$extension}");
|
|
$im->thumbnailImage($format->largeur, $format->hauteur, true);
|
|
$im->writeImage($fp);
|
|
$im->destroy();
|
|
unset($im);
|
|
}
|
|
|
|
/**
|
|
* Returns the media folder path name
|
|
*
|
|
* @return string
|
|
* @throws \ErrorException If creating the folder fails.
|
|
*/
|
|
public function getMediaFolder(): string
|
|
{
|
|
$mediaPath = "medias/";
|
|
$directories = Storage::allDirectories($mediaPath);
|
|
$selectedFolder = "";
|
|
|
|
// * on obtient le dernier dossier créé
|
|
/** @var string $foldername */
|
|
foreach ($directories as $key => $foldername) {
|
|
if ($selectedFolder < $foldername) {
|
|
$selectedFolder = $foldername;
|
|
}
|
|
}
|
|
// * si on n'a pas de dossier, on le créé
|
|
if ($selectedFolder == "") {
|
|
$selectedFolder = $mediaPath . uniqid();
|
|
if (!Storage::makeDirectory($selectedFolder)) {
|
|
throw new \ErrorException("Could not create $selectedFolder");
|
|
}
|
|
} else {
|
|
// * on compte le nombre de fichier
|
|
$files = Storage::allFiles($selectedFolder);
|
|
// * si on en a plus de 1000, on créé un nouveau dossier
|
|
if (count($files) > 1000) {
|
|
$selectedFolder = $mediaPath . uniqid();
|
|
if (!Storage::makeDirectory($selectedFolder)) {
|
|
throw new \ErrorException("Could not create $selectedFolder");
|
|
}
|
|
}
|
|
}
|
|
return $selectedFolder;
|
|
}
|
|
|
|
public function fixIntegerOverflow($size)
|
|
{
|
|
if ($size < 0) {
|
|
$size += 2.0 * (PHP_INT_MAX + 1);
|
|
}
|
|
return $size;
|
|
}
|
|
|
|
/**
|
|
* Convert file size to human readable string
|
|
*
|
|
* @param integer $octet
|
|
* @param integer $precision
|
|
* @return string
|
|
*/
|
|
public function formatBytes(int $octet, int $precision = 2): string
|
|
{
|
|
// * Array contenant les differents unités
|
|
$unite = array('octet', 'Ko', 'Mo', 'Go');
|
|
|
|
switch (true) {
|
|
// * octet
|
|
case $octet < 1000:
|
|
return $octet . $unite[0];
|
|
// * ko
|
|
case $octet < 1000000:
|
|
return $octet . $unite[1];
|
|
// * Mo ou Go
|
|
default:
|
|
if ($octet < 1000000000) {
|
|
// * Mo
|
|
$mo = round($octet / (1024 * 1024), $precision);
|
|
return $mo . $unite[2];
|
|
} else {
|
|
// * Go
|
|
$go = round($octet / (1024 * 1024 * 1024), $precision);
|
|
return $go . $unite[3];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renvoi le chemin attendu d'un média selon le format demandé
|
|
*
|
|
* @param \App\Models\Media $media
|
|
* @param \App\Models\Format $format
|
|
* @return string
|
|
* @throws \ErrorException If Format is not handled.
|
|
*/
|
|
public function getMediaPath(Media $media, Format $format): string
|
|
{
|
|
// * format spécifique
|
|
if ($format->system) {
|
|
if (in_array($media->extension, array("gif", "jpeg", "jpg", "png", "pdf", "ai", "psd"))) {
|
|
return public_path("/{$media->folder}{$media->uid}_{$format->libelle}.{$format->extension}");
|
|
}
|
|
return public_path("/{$media->folder}{$media->uid}.{$media->extension}");
|
|
}
|
|
// * format système (thumb et preview)
|
|
if ($format->system) {
|
|
if (in_array($media->extension, array("gif", "jpeg", "jpg", "png"))) {
|
|
// * Gestion du cas de format qui fixe l'extension
|
|
if ($format->extension != '') {
|
|
$file_extension = $format->extension;
|
|
} else {
|
|
$file_extension = $media->extension;
|
|
}
|
|
return public_path("/{$media->folder}{$media->uid}_{$format->libelle}.{$file_extension}");
|
|
} elseif (in_array($media->extension, array("pdf", "ai", "psd"))) {
|
|
return public_path("/{$media->folder}{$media->uid}_{$format->libelle}.png");
|
|
}
|
|
return public_path("/{$media->folder}.{$media->uid}.{$media->extension}");
|
|
}
|
|
throw new \ErrorException("Unhandled Format $format->id $format->libelle");
|
|
}
|
|
}
|