2022-09-20 19:59:52 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Rules;
|
|
|
|
|
|
|
|
use App\Http\Controllers\Forms\PublicFormController;
|
2024-02-23 10:54:12 +00:00
|
|
|
use App\Models\Forms\Form;
|
2022-09-20 19:59:52 +00:00
|
|
|
use App\Service\Storage\StorageFileNameParser;
|
|
|
|
use Illuminate\Contracts\Validation\Rule;
|
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
|
|
|
class StorageFile implements Rule
|
|
|
|
{
|
|
|
|
public string $error = 'Invalid file.';
|
|
|
|
|
2024-02-29 09:48:19 +00:00
|
|
|
public function __construct(public int $maxSize, public array $fileTypes = [], public ?Form $form = null)
|
2022-09-20 19:59:52 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* File can have 2 formats:
|
2024-02-29 09:48:19 +00:00
|
|
|
* - file-name_{uuid}.{ext}
|
2022-09-20 19:59:52 +00:00
|
|
|
* - {uuid}
|
|
|
|
*
|
|
|
|
* @param string $attribute
|
|
|
|
* @param mixed $value
|
|
|
|
*/
|
|
|
|
public function passes($attribute, $value): bool
|
|
|
|
{
|
2023-10-20 09:00:35 +00:00
|
|
|
// If full path then no need to validate
|
2024-02-23 10:54:12 +00:00
|
|
|
if (filter_var($value, FILTER_VALIDATE_URL) !== false) {
|
2023-10-20 09:00:35 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-04-26 15:05:02 +00:00
|
|
|
// This is use when updating a record, and file uploads aren't changed.
|
2024-02-23 10:54:12 +00:00
|
|
|
if ($this->form) {
|
2023-04-26 15:05:02 +00:00
|
|
|
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id);
|
2024-02-23 10:54:12 +00:00
|
|
|
if (Storage::exists($newPath.'/'.$value)) {
|
2023-04-26 15:05:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 19:59:52 +00:00
|
|
|
$fileNameParser = StorageFileNameParser::parse($value);
|
2024-02-23 10:54:12 +00:00
|
|
|
if (! $uuid = $fileNameParser->uuid) {
|
2022-09-20 19:59:52 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$filePath = PublicFormController::TMP_FILE_UPLOAD_PATH.$uuid;
|
2024-02-23 10:54:12 +00:00
|
|
|
if (! Storage::exists($filePath)) {
|
2022-09-20 19:59:52 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Storage::size($filePath) > $this->maxSize) {
|
|
|
|
$this->error = 'File is too large.';
|
2024-02-23 10:54:12 +00:00
|
|
|
|
2022-09-20 19:59:52 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count($this->fileTypes) > 0) {
|
2024-02-23 10:54:12 +00:00
|
|
|
$this->error = 'Incorrect file type. Allowed only: '.implode(',', $this->fileTypes);
|
2024-02-29 09:48:19 +00:00
|
|
|
return collect($this->fileTypes)->map(function ($type) {
|
|
|
|
return strtolower($type);
|
|
|
|
})->contains(strtolower($fileNameParser->extension));
|
2022-09-20 19:59:52 +00:00
|
|
|
}
|
2024-02-23 10:54:12 +00:00
|
|
|
|
2022-09-20 19:59:52 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function message(): string
|
|
|
|
{
|
|
|
|
return $this->error;
|
|
|
|
}
|
|
|
|
}
|