Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.5.13 - improved file uploads and file model functions #116

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fleetbase/core-api",
"version": "1.5.12",
"version": "1.5.13",
"description": "Core Framework and Resources for Fleetbase API",
"keywords": [
"fleetbase",
Expand Down
8 changes: 1 addition & 7 deletions src/Http/Controllers/Internal/v1/FileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@ public function upload(UploadFileRequest $request)

// Upload the file to storage disk
try {
$path = $request->file->storeAs(
$path,
$fileName,
[
'disk' => $disk,
]
);
$path = $request->file->storeAs($path, $fileName, ['disk' => $disk]);
} catch (\Throwable $e) {
return response()->error($e->getMessage());
}
Expand Down
129 changes: 100 additions & 29 deletions src/Models/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Fleetbase\Casts\PolymorphicType;
use Fleetbase\Support\Utils;
use Fleetbase\Traits\HasApiModelBehavior;
use Fleetbase\Traits\HasMetaAttributes;
use Fleetbase\Traits\HasPublicId;
use Fleetbase\Traits\HasUuid;
use Fleetbase\Traits\SendsWebhooks;
Expand All @@ -25,6 +26,7 @@ class File extends Model
use HasUuid;
use HasPublicId;
use HasApiModelBehavior;
use HasMetaAttributes;
use HasSlug;
use LogsActivity;
use SendsWebhooks;
Expand Down Expand Up @@ -140,7 +142,7 @@ public function getFilesystem(?string $disk = null): \Illuminate\Contracts\Files
public function getUrlAttribute()
{
$disk = $this->getDisk();
/** @var $filesystem \Illuminate\Support\Facades\Storage */
/** @var Storage $filesystem */
$filesystem = $this->getFilesystem();

if ($disk === 's3' || $disk === 'gcs') {
Expand Down Expand Up @@ -179,31 +181,81 @@ public function setUploader(User $uploader): File
}

/**
* Retrieves the MIME type of the file based on its extension.
* Retrieves the MIME type associated with the file.
*
* @param string|null $extension optional extension to determine the MIME type; defaults to the instance's extension
* @param string|null $extension Optional file extension to determine the MIME type. If null, it will use the default extension.
*
* @return string the MIME type of the file
* @return string|null the MIME type corresponding to the given extension, or null if not found
*/
public function getMimeType($extension = null)
public function getMimeType($extension = null): ?string
{
return static::getFileMimeType($extension ?? $this->extension);
return static::getFileMimeType($extension);
}

/**
* Extracts the file extension from the original filename, considering known multi-part extensions.
*
* @return string|null The file extension, including multi-part extensions (e.g., 'tar.gz'), or null if none found.
*/
public function getExtensionFromFilename(): ?string
{
return static::parseExtensionFromFilename($this->original_filename);
}

/**
* Parses the file extension from the given filename, accounting for known multi-part extensions.
*
* @param string $filename the filename from which to extract the extension
*
* @return string|null the file extension, including multi-part extensions if applicable
*/
public static function parseExtensionFromFilename(string $filename): ?string
{
$knownExtensions = ['tar.gz', 'tar.bz2', 'tar.xz', 'tar.Z'];

foreach ($knownExtensions as $ext) {
if (substr($filename, -strlen($ext)) === $ext) {
return $ext;
}
}

// If no known multi-part extension is found, return the last extension
return pathinfo($filename, PATHINFO_EXTENSION);
}

/**
* Retrieves the file extension associated with the file, derived from the content type or original filename.
*
* @return string|null the file extension, or null if it cannot be determined
*/
public function getExtension(): ?string
{
$mimeType = $this->content_type;
if (!$mimeType) {
$extensionFromFileName = $this->getExtensionFromFilename();
$mimeType = static::getMimeTypeFromExtension($extensionFromFileName);
}

return $mimeType ? static::getExtensionFromMimeType($this->content_type) : $this->getExtensionFromFilename();
}

/**
* Determines the file extension based on a given MIME type.
*
* @param string $mimeType the MIME type for which to find the corresponding file extension
*
* @return string the file extension associated with the given MIME type
* @return string|null the file extension associated with the given MIME type
*/
public static function getExtensionFromMimeType($mimeType)
public static function getExtensionFromMimeType($mimeType): ?string
{
$mimes = new MimeTypes();
$extension = $mimes->getExtension($mimeType);

if (!$extension) {
$extension = explode('/', $mimeType)[1];
$extensionSegments = explode('/', $mimeType);
if (count($extensionSegments) > 1) {
$extension = $extensionSegments[1];
}
}

return $extension;
Expand All @@ -214,9 +266,9 @@ public static function getExtensionFromMimeType($mimeType)
*
* @param string $extension the file extension for which to find the MIME type
*
* @return string the MIME type corresponding to the given file extension
* @return string|null the MIME type corresponding to the given file extension, or null if not found
*/
public static function getMimeTypeFromExtension($extension)
public static function getMimeTypeFromExtension($extension): ?string
{
$mimes = new MimeTypes();

Expand All @@ -228,13 +280,39 @@ public static function getMimeTypeFromExtension($extension)
*
* @param string $extension the file extension to look up
*
* @return string the MIME type for the given extension
* @return string|null the MIME type for the given extension
*/
public static function getFileMimeType($extension)
public static function getFileMimeType($extension): ?string
{
return static::getMimeTypeFromExtension($extension);
}

/**
* Retrieves the MIME type from an uploaded file, attempting to determine it from the file's extension if necessary.
*
* @param UploadedFile $file the uploaded file from which to extract the MIME type
*
* @return string|null the MIME type of the uploaded file, or null if it cannot be determined
*/
public static function getUploadedFileMimeType(UploadedFile $file): ?string
{
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$parsedExtension = static::parseExtensionFromFilename($filename);
$mimeType = $file->getMimeType();
if (!$mimeType) {
if ($parsedExtension) {
$mimeType = static::getFileMimeType($parsedExtension);
}

if (!$mimeType && $extension) {
$mimeType = static::getFileMimeType($extension);
}
}

return $mimeType;
}

/**
* Creates a new file instance from an uploaded file.
*
Expand All @@ -249,26 +327,20 @@ public static function getFileMimeType($extension)
*/
public static function createFromUpload(UploadedFile $file, $path, $type = null, $size = null, $disk = null, $bucket = null): ?File
{
$extension = $file->getClientOriginalExtension();

if (is_null($disk)) {
$disk = config('filesystems.default');
}

if (is_null($bucket)) {
$bucket = config('filesystems.disks.' . $disk . '.bucket', config('filesystems.disks.s3.bucket'));
}
$disk = is_null($disk) ? config('filesystems.default') : $disk;
$bucket = is_null($bucket) ? config('filesystems.disks.' . $disk . '.bucket', config('filesystems.disks.s3.bucket')) : $bucket;
$size = is_null($size) ? $file->getSize() : $size;

$data = [
'company_uuid' => session('company'),
'uploader_uuid' => session('user'),
'original_filename' => $file->getClientOriginalName(),
'content_type' => static::getFileMimeType($extension),
'content_type' => static::getUploadedFileMimeType($file),
'disk' => $disk,
'path' => $path,
'bucket' => $bucket,
'type' => $type,
'file_size' => $size ?? $file->getSize(),
'file_size' => $size,
];

return static::create($data);
Expand Down Expand Up @@ -402,14 +474,13 @@ public static function randomFileName(?string $extension = 'png')
*
* @return string the generated random file name
*/
public static function randomFileNameFromRequest($request, ?string $extension = 'png')
public static function randomFileNameFromRequest($request, string $filename = 'file', ?string $extension = null)
{
/** @var Request|\Fleetbase\Http\Requests\Internal\UploadFileRequest $request */
/** @var \Illuminate\Http\File|Symfony\Component\HttpFoundation\File\File|\Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $request->file;

if ($request->hasFile('file')) {
$extension = strtolower($file->getClientOriginalExtension());
if ($request->hasFile($filename)) {
$file = $request->file($filename);
$extension = $extension ?? strtolower($file->getClientOriginalExtension());
$extension = Str::startsWith($extension, '.') ? $extension : '.' . $extension;
$sqids = new \Sqids\Sqids();

Expand Down
Loading