feat(tenant): share website type favicon attachment
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
private const FILENAME = 'onticket_favicon.svg';
|
||||
|
||||
/** @var list<string> */
|
||||
private const WEBSITE_TYPE_CODES = ['shopit', 'onticket'];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$websiteTypes = DB::table('website_type')
|
||||
->whereIn('codigo', self::WEBSITE_TYPE_CODES)
|
||||
->get(['codigo', 'favicon_id']);
|
||||
|
||||
if ($websiteTypes->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$faviconIds = $websiteTypes
|
||||
->pluck('favicon_id')
|
||||
->filter()
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
if (
|
||||
$faviconIds->count() === 1
|
||||
&& DB::table('attachments')
|
||||
->where('id', $faviconIds->first())
|
||||
->where('filename', self::FILENAME)
|
||||
->exists()
|
||||
&& $websiteTypes->every(
|
||||
fn (object $websiteType): bool => $websiteType->favicon_id === $faviconIds->first()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sourcePath = public_path('images/website_types/'.self::FILENAME);
|
||||
|
||||
if (! is_file($sourcePath)) {
|
||||
throw new RuntimeException("Favicon not found at path: {$sourcePath}");
|
||||
}
|
||||
|
||||
$contents = file_get_contents($sourcePath);
|
||||
|
||||
if ($contents === false) {
|
||||
throw new RuntimeException("Could not read favicon at path: {$sourcePath}");
|
||||
}
|
||||
|
||||
$key = (string) Str::uuid();
|
||||
$storedPath = "website-types/{$key}.svg";
|
||||
|
||||
if (! Storage::disk('s3')->put($storedPath, $contents)) {
|
||||
throw new RuntimeException("Could not store favicon at path: {$storedPath}");
|
||||
}
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($contents, $key, $storedPath): void {
|
||||
$attachmentId = DB::table('attachments')->insertGetId([
|
||||
'key' => $key,
|
||||
'path' => $storedPath,
|
||||
'filename' => self::FILENAME,
|
||||
'type' => 'image',
|
||||
'mime_type' => 'image/svg+xml',
|
||||
'extension' => 'svg',
|
||||
'size' => strlen($contents),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
DB::table('website_type')
|
||||
->whereIn('codigo', self::WEBSITE_TYPE_CODES)
|
||||
->update([
|
||||
'favicon_id' => $attachmentId,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
});
|
||||
} catch (Throwable $throwable) {
|
||||
Storage::disk('s3')->delete($storedPath);
|
||||
|
||||
throw $throwable;
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// The shared attachment may be in use outside these website types.
|
||||
// Keep this data migration irreversible to avoid deleting an active asset.
|
||||
}
|
||||
};
|
||||
@@ -36,6 +36,7 @@ class WebsiteTypeSeeder extends Seeder
|
||||
...self::PRESENTATION,
|
||||
'site_logo' => $this->onTicketLogo(),
|
||||
'footer_logo' => $this->onTicketFooterLogo(),
|
||||
'favicon' => $this->onTicketFavicon(),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -70,6 +71,7 @@ class WebsiteTypeSeeder extends Seeder
|
||||
...self::PRESENTATION,
|
||||
'site_logo' => $this->onTicketLogo(),
|
||||
'footer_logo' => $this->onTicketFooterLogo(),
|
||||
'favicon' => $shopIt->favicon()->firstOrFail()->key,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -175,4 +177,21 @@ class WebsiteTypeSeeder extends Seeder
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
private function onTicketFavicon(): UploadedFile
|
||||
{
|
||||
$path = public_path('images/website_types/onticket_favicon.svg');
|
||||
|
||||
if (! file_exists($path)) {
|
||||
throw new RuntimeException("OnTicket favicon not found at path: {$path}");
|
||||
}
|
||||
|
||||
return new UploadedFile(
|
||||
$path,
|
||||
'onticket_favicon.svg',
|
||||
'image/svg+xml',
|
||||
null,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user