Files
amare/app/Support/PublicImageUploadRules.php
Manoel Freitas cafb1167ac feat: wire Resend mail and Cloudflare R2 storage (#4)
Add production provider deps/config so transactional email and CMS
media can use Resend and a dedicated r2 disk with custom-domain URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-29 21:00:16 -03:00

96 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support;
use Filament\Forms\Components\BaseFileUpload;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Get;
use Illuminate\Validation\Rules\File;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
final class PublicImageUploadRules
{
/** @var list<string> */
public const ALLOWED_MIMES = ['image/jpeg', 'image/png', 'image/webp'];
/** @var list<string> */
public const ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png', 'webp'];
public const MAX_SIZE_KILOBYTES = 10240;
public static function fileUpload(string $name, string $label, string $directory = 'content'): FileUpload
{
return FileUpload::make($name)
->label($label)
->disk(self::disk())
->directory($directory)
->acceptedFileTypes(self::ALLOWED_MIMES)
->maxSize(self::MAX_SIZE_KILOBYTES)
->rules(self::validationRules())
->validationMessages(self::validationMessages())
->getUploadedFileNameForStorageUsing(
fn ($file): string => (string) str()->uuid().'.'.$file->getClientOriginalExtension(),
)
->saveUploadedFileUsing(function (BaseFileUpload $component, TemporaryUploadedFile $file): ?string {
$path = $component->saveUploadedFile($file);
if (filled($path)) {
ResponsiveImage::generate((string) $path, $component->getDiskName());
}
return $path;
})
->deleteUploadedFileUsing(function (BaseFileUpload $component, string $file): void {
ResponsiveImage::delete($file, $component->getDiskName());
});
}
public static function altTextField(string $name, string $imageField, string $label = 'Texto alternativo'): TextInput
{
return TextInput::make($name)
->label($label)
->required(fn (Get $get): bool => filled($get($imageField)))
->validationMessages([
'required' => 'O texto alternativo é obrigatório quando uma imagem é enviada.',
])
->maxLength(255);
}
/**
* @return list<File|string>
*/
public static function validationRules(): array
{
return [
File::types(self::ALLOWED_EXTENSIONS)->max(self::MAX_SIZE_KILOBYTES),
'extensions:'.implode(',', self::ALLOWED_EXTENSIONS),
];
}
/**
* @return array<string, string>
*/
public static function validationMessages(): array
{
return [
'file' => 'A imagem enviada é inválida.',
'mimes' => 'A imagem deve ser um arquivo JPG, JPEG, PNG ou WEBP.',
'mimetypes' => 'A imagem deve ser um arquivo JPG, JPEG, PNG ou WEBP.',
'extensions' => 'A imagem deve ser um arquivo JPG, JPEG, PNG ou WEBP.',
'max' => 'A imagem não pode ter mais de 10 MB.',
];
}
public static function disk(): string
{
return match (config('filesystems.default')) {
'r2' => 'r2',
's3' => 's3',
default => 'public',
};
}
}