2023-10-02 23:10:49 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Lucent\File;
|
|
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
use Exception;
|
|
|
|
|
use Illuminate\Contracts\Filesystem\Filesystem;
|
2023-10-02 23:10:49 +03:00
|
|
|
use Illuminate\Http\UploadedFile;
|
2024-08-19 17:48:10 +03:00
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
use Intervention\Image\ImageManagerStatic;
|
2023-10-04 13:32:30 +03:00
|
|
|
use Lucent\Channel\ChannelService;
|
2024-09-07 13:22:58 +03:00
|
|
|
use Lucent\Database\Database;
|
2023-10-02 23:10:49 +03:00
|
|
|
use Lucent\LucentException;
|
2024-08-19 17:48:10 +03:00
|
|
|
use Lucent\Record\FileData as RecordFile;
|
2023-10-04 13:32:30 +03:00
|
|
|
use Lucent\Record\QueryRecord;
|
2024-08-19 17:48:10 +03:00
|
|
|
use Lucent\Schema\FilesSchema;
|
2024-09-19 23:36:43 +03:00
|
|
|
use Lucent\Schema\Schema;
|
2024-08-19 17:48:10 +03:00
|
|
|
use Spatie\ImageOptimizer\OptimizerChainFactory;
|
2023-10-02 23:10:49 +03:00
|
|
|
|
|
|
|
|
class FileService
|
|
|
|
|
{
|
|
|
|
|
|
2023-10-04 13:32:30 +03:00
|
|
|
public function __construct(
|
|
|
|
|
public ChannelService $channelService
|
|
|
|
|
)
|
2023-10-02 23:10:49 +03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-04 13:32:30 +03:00
|
|
|
public function getPath(QueryRecord $file): string
|
|
|
|
|
{
|
2024-08-23 20:58:45 +03:00
|
|
|
return $this->channelService->channel->filesUrl . "/" . $file->_file->path;
|
2023-10-04 13:32:30 +03:00
|
|
|
}
|
|
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
public function createFromUrl(FilesSchema $schema, string $url): FileUploadResult
|
2023-10-02 23:10:49 +03:00
|
|
|
{
|
2024-08-19 17:48:10 +03:00
|
|
|
$pathinfo = pathinfo($url);
|
|
|
|
|
$contents = file_get_contents($url);
|
|
|
|
|
if ($contents === false) {
|
|
|
|
|
throw new LucentException("Failed to upload file from url");
|
|
|
|
|
}
|
|
|
|
|
$file = '/tmp/' . $pathinfo['basename'];
|
|
|
|
|
file_put_contents($file, $contents);
|
|
|
|
|
$uploadedFile = new UploadedFile($file, $pathinfo['basename']);
|
|
|
|
|
return $this->upload($schema, $uploadedFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function upload(FilesSchema $schema, UploadedFile $file): FileUploadResult
|
|
|
|
|
{
|
|
|
|
|
$originalName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
|
|
|
|
$extension = pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
|
|
|
|
|
$originalFilename = $file->getClientOriginalName();
|
|
|
|
|
$filename = $this->createFileName($originalName, $extension);
|
|
|
|
|
$mimetype = $file->getMimeType();
|
|
|
|
|
|
|
|
|
|
$optimizerChain = OptimizerChainFactory::create();
|
|
|
|
|
$optimizerChain->setTimeout(30)->optimize($file->getPathName());
|
|
|
|
|
|
|
|
|
|
$checksum = sha1_file($file);
|
|
|
|
|
$recordId = $this->checkDuplicate($schema->name, $checksum, $file->getSize());
|
|
|
|
|
|
|
|
|
|
if (!empty($recordId)) {
|
2023-10-02 23:10:49 +03:00
|
|
|
return new FileUploadResult(
|
2024-08-19 17:48:10 +03:00
|
|
|
recordFile: null,
|
|
|
|
|
duplicateId: $recordId,
|
|
|
|
|
isDuplicate: true
|
2023-10-02 23:10:49 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-19 23:36:43 +03:00
|
|
|
$disk = $this->loadDisk($schema);
|
2024-08-19 17:48:10 +03:00
|
|
|
$path = $schema->path . "/" . $filename;
|
|
|
|
|
$res = $disk->put(
|
|
|
|
|
$path,
|
|
|
|
|
file_get_contents($file),
|
|
|
|
|
// 'public' // now managed by aws policy
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ($res === false) {
|
|
|
|
|
throw new LucentException("File $filename not uploaded");
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|
|
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
$this->createThumbnail($disk, $schema->path, $filename, $file);
|
|
|
|
|
|
|
|
|
|
list($width, $height) = $this->isImage($mimetype) ? getimagesize($file) : [0, 0];
|
|
|
|
|
$recordFile = new RecordFile(
|
|
|
|
|
originalName: $originalFilename,
|
|
|
|
|
mime: $mimetype,
|
|
|
|
|
path: $path,
|
|
|
|
|
size: $file->getSize(),
|
|
|
|
|
width: $width,
|
|
|
|
|
height: $height,
|
|
|
|
|
checksum: $checksum
|
|
|
|
|
);
|
|
|
|
|
|
2023-10-02 23:10:49 +03:00
|
|
|
return new FileUploadResult(
|
2024-08-19 17:48:10 +03:00
|
|
|
recordFile: $recordFile,
|
|
|
|
|
duplicateId: "",
|
|
|
|
|
isDuplicate: false
|
2023-10-02 23:10:49 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
private function createFileName(string $originalName, string $extension): string
|
2023-10-02 23:10:49 +03:00
|
|
|
{
|
2024-08-19 17:48:10 +03:00
|
|
|
return Str::slug($originalName, '-') . '-' . uniqid() . '.' . $extension;
|
|
|
|
|
}
|
2023-10-02 23:10:49 +03:00
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
private function isImage(string $mimetype): bool
|
|
|
|
|
{
|
|
|
|
|
$imageMimes = ['image/webp', 'image/gif', 'image/jpeg', 'image/png', 'image/tiff'];
|
|
|
|
|
return in_array($mimetype, $imageMimes);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-19 23:36:43 +03:00
|
|
|
public function loadDisk(Schema $schema): Filesystem
|
2024-08-19 17:48:10 +03:00
|
|
|
{
|
2024-09-19 23:36:43 +03:00
|
|
|
return Storage::disk($schema->disk);
|
|
|
|
|
|
2024-08-19 17:48:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function checkDuplicate(string $schemaName, string $checksum, int $filesize): string
|
|
|
|
|
{
|
|
|
|
|
|
2024-09-07 13:22:58 +03:00
|
|
|
$record = Database::make()->table("records")
|
2024-08-19 17:48:10 +03:00
|
|
|
->where("schema", $schemaName)
|
|
|
|
|
->where("_file->checksum", $checksum)
|
|
|
|
|
->where("_file->size", $filesize)
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
return $record->id ?? "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function createThumbnail(Filesystem $disk, string $schemaPath, string $filename, UploadedFile $file): void
|
|
|
|
|
{
|
2024-08-23 20:58:45 +03:00
|
|
|
$thumbDir = "thumbs/" . $schemaPath . "/";
|
|
|
|
|
// if (!file_exists($thumbDir)) {
|
|
|
|
|
// make_dir_r($thumbDir);
|
|
|
|
|
// }
|
2024-08-19 17:48:10 +03:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
ImageManagerStatic::configure(['driver' => 'imagick']);
|
|
|
|
|
$image = ImageManagerStatic::make($file);
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
|
logger($e->getMessage());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$image->fit(300, 300);
|
|
|
|
|
try {
|
2024-09-19 23:36:43 +03:00
|
|
|
$disk->put($thumbDir . $filename, $image->encode('webp', 75));
|
2024-08-23 20:58:45 +03:00
|
|
|
// $image->encode('webp', 75)->save($thumbDir . $filename);
|
2024-08-19 17:48:10 +03:00
|
|
|
} catch (Exception $e) {
|
|
|
|
|
logger($e->getMessage());
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|
|
|
|
|
}
|
2024-08-19 17:48:10 +03:00
|
|
|
|
|
|
|
|
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|