- New SportsMatch model/controller and sports UI components/modal - Move share-modal to a reusable x-share-modal/x-share-button component - Add VideoSharedWithUser notification and share-to-members flow - Device/user-agent tracking on views, downloads, share accesses - ProfileVisit model + migration; subscription source tracking - Email thumbnail support; remove stale TODO files
60 lines
1.9 KiB
PHP
60 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use App\Models\Video;
|
|
use App\Services\NasSyncService;
|
|
|
|
/**
|
|
* Resolves a video's thumbnail to a local absolute file path so it can be
|
|
* embedded inline (CID) in transactional emails.
|
|
*
|
|
* Remote mail clients (notably Gmail's image proxy) cannot reliably fetch the
|
|
* dynamic /media/thumbnails route — it sits behind Cloudflare and PHP, so the
|
|
* proxy may be challenged or time out, leaving a broken image. Embedding the
|
|
* bytes directly in the message removes that external dependency entirely.
|
|
*/
|
|
class EmailThumbnail
|
|
{
|
|
public static function localPath(?Video $video): ?string
|
|
{
|
|
if (! $video || ! $video->thumbnail) {
|
|
return null;
|
|
}
|
|
|
|
$thumb = $video->thumbnail;
|
|
$nas = app(NasSyncService::class);
|
|
|
|
// NAS-mirrored path format: "users/{slug}/videos/{song}/…"
|
|
if (str_starts_with($thumb, 'users/')) {
|
|
$local = storage_path('app/' . $thumb);
|
|
if (file_exists($local)) {
|
|
return $local;
|
|
}
|
|
|
|
@mkdir(dirname($local), 0755, true);
|
|
|
|
// The DB path mirrors the NAS path exactly — try it directly first.
|
|
if ($nas->ensureLocalAsset($local, $thumb)) {
|
|
return $local;
|
|
}
|
|
|
|
// Extension may differ on NAS (e.g. canonical thumb.webp).
|
|
$dir = $nas->resolveVideoDir($video);
|
|
$ext = pathinfo($thumb, PATHINFO_EXTENSION) ?: 'jpg';
|
|
foreach (["thumb.webp", "thumb.{$ext}"] as $nasFile) {
|
|
if ($nas->ensureLocalAsset($local, "{$dir}/{$nasFile}")) {
|
|
return $local;
|
|
}
|
|
}
|
|
|
|
return file_exists($local) ? $local : null;
|
|
}
|
|
|
|
// Legacy flat filename format.
|
|
$local = storage_path('app/public/thumbnails/' . $thumb);
|
|
|
|
return file_exists($local) ? $local : null;
|
|
}
|
|
}
|