This commit is contained in:
2023-04-22 21:18:07 +10:00
parent 84bfd3cda2
commit a663e2bd56
22 changed files with 384 additions and 143 deletions

View File

@@ -8,6 +8,7 @@ use App\Http\Requests\MediaRequest;
use App\Models\Media;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Laravel\Sanctum\PersonalAccessToken;
class MediaController extends ApiController
@@ -119,19 +120,36 @@ class MediaController extends ApiController
if (MediaConductor::updatable($medium) === true) {
$file = $request->file('file');
if ($file !== null) {
if ($file->getSize() > Media::maxUploadSize()) {
return $this->respondTooLarge();
if ($file->isValid() !== true) {
switch ($file->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
return $this->respondTooLarge();
case UPLOAD_ERR_PARTIAL:
return $this->respondWithErrors(['file' => 'The file upload was interrupted.']);
default:
return $this->respondWithErrors(['file' => 'An error occurred uploading the file to the server.']);
}
}
if ($medium->updateFile($file) === false) {
if ($file->getSize() > Media::getMaxUploadSize()) {
return $this->respondTooLarge();
}
}
$medium->update($request->all());
if ($file !== null) {
try {
$medium->updateWithUploadedFile($file);
} catch (\Exception $e) {
return $this->respondWithErrors(
['file' => 'The file could not be stored on the server'],
['file' => $e->getMessage()],
HttpResponseCodes::HTTP_INTERNAL_SERVER_ERROR
);
}
}//end if
}
$medium->update($request->all());
return $this->respondAsResource(MediaConductor::model($request, $medium));
}//end if

View File

@@ -44,11 +44,12 @@ class StoreUploadedFileJob implements ShouldQueue
*/
protected $replaceExisting;
/**
* Create a new job instance.
*
* @param Media $media The media model.
* @param string $filePath The uploaded file.
* @param Media $media The media model.
* @param string $filePath The uploaded file.
* @param boolean $replaceExisting Replace existing files.
* @return void
*/
@@ -74,31 +75,30 @@ class StoreUploadedFileJob implements ShouldQueue
$this->media->save();
if (strlen($this->uploadedFilePath) > 0) {
if (Storage::disk($storageDisk)->exists($fileName) == false || $this->replaceExisting == true) {
if (Storage::disk($storageDisk)->exists($fileName) === false || $this->replaceExisting === true) {
Storage::disk($storageDisk)->putFileAs('/', new SplFileInfo($this->uploadedFilePath), $fileName);
Log::info("uploading file {$storageDisk} / {$fileName} / {$this->uploadedFilePath}");
} else {
Log::info("file {$fileName} already exists in {$storageDisk} / {$this->uploadedFilePath}. Not replacing file and using local {$fileName} for variants.");
}
} else {
if (Storage::disk($storageDisk)->exists($fileName) == true) {
if (Storage::disk($storageDisk)->exists($fileName) === true) {
Log::info("file {$fileName} already exists in {$storageDisk} / {$this->uploadedFilePath}. No local {$fileName} for variants, downloading from CDN.");
$readStream = Storage::disk($storageDisk)->readStream($fileName);
$tempFilePath = tempnam(sys_get_temp_dir(), 'download-');
$writeStream = fopen($tempFilePath, 'w');
while (!feof($readStream)) {
while (feof($readStream) !== true) {
fwrite($writeStream, fread($readStream, 8192));
}
fclose($readStream);
fclose($writeStream);
$this->uploadedFilePath = $tempFilePath;
} else {
$errorStr = "cannot upload file {$storageDisk} / {$fileName} / {$this->uploadedFilePath} as temp file is empty";
Log::info($errorStr);
throw new \Exception($errorStr);
}
}
}//end if
if (strpos($this->media->mime_type, 'image/') === 0) {
$this->media->status = "Optimizing image";
@@ -160,7 +160,7 @@ class StoreUploadedFileJob implements ShouldQueue
}//end if
} else {
Log::info("variant {$variantName} already exists for file {$fileName}");
}
}//end if
}//end foreach
// Set missing variants to the largest available variant

View File

@@ -206,7 +206,7 @@ class Media extends Model
*/
public function getUrlAttribute()
{
if(isset($this->attributes['name'])) {
if (isset($this->attributes['name']) === true) {
$url = config("filesystems.disks.$this->storage.url");
return "$url/$this->name";
}
@@ -247,6 +247,28 @@ class Media extends Model
* @return null|Media The result or null if not successful.
*/
public static function createFromUploadedFile(Request $request, UploadedFile $file)
{
$request->merge([
'title' => $request->get('title', ''),
'name' => '',
'size' => 0,
'mime_type' => '',
'status' => '',
]);
$mediaItem = $request->user()->media()->create($request->all());
$mediaItem->updateWithUploadedFile($file);
return $mediaItem;
}
/**
* Update Media with UploadedFile data.
*
* @param Illuminate\Http\UploadedFile $file The file.
* @return null|Media The media item.
*/
public function updateWithUploadedFile(UploadedFile $file)
{
if ($file === null || $file->isValid() !== true) {
throw new \Exception('The file is invalid.', self::INVALID_FILE_ERROR);
@@ -261,34 +283,40 @@ class Media extends Model
throw new \Exception('The file name already exists in storage.', self::FILE_NAME_EXISTS_ERROR);
}
$request->merge([
'title' => $request->get('title', $name),
'name' => $name,
'size' => $file->getSize(),
'mime_type' => $file->getMimeType(),
'status' => 'Processing media',
]);
// remove file if there is an existing entry in this medium item
if (strlen($this->name) > 0 && strlen($this->storage) > 0) {
Storage::disk($this->storage)->delete($this->name);
foreach ($this->variants as $variantName => $fileName) {
Storage::disk($this->storage)->delete($fileName);
}
$mediaItem = $request->user()->media()->create($request->all());
try {
$temporaryFilePath = tempnam(sys_get_temp_dir(), 'upload');
$temporaryDirectoryPath = dirname($temporaryFilePath);
$file->move($temporaryDirectoryPath, basename($temporaryFilePath));
} catch (\Exception $e) {
throw new \Exception('Could not temporarily store file. ' . $e->getMessage(), self::TEMP_FILE_ERROR);
$this->name = '';
$this->variants = [];
}
if (strlen($this->title) === 0) {
$this->title = $name;
}
$this->name = $name;
$this->size = $file->getSize();
$this->mime_type = $file->getMimeType();
$this->status = 'Processing media';
$this->save();
$temporaryFilePath = tempnam(sys_get_temp_dir(), 'upload');
copy($file->path(), $temporaryFilePath);
try {
StoreUploadedFileJob::dispatch($mediaItem, $temporaryFilePath)->onQueue('media');
StoreUploadedFileJob::dispatch($this, $temporaryFilePath)->onQueue('media');
} catch (\Exception $e) {
$mediaItem->delete();
$mediaItem = null;
$this->status = 'Error';
$this->save();
throw $e;
}//end try
return $mediaItem;
return $this;
}
/**