Prílohy a vložené médiá
Každý komentár vlastní jednu skupinu attachments cez Media Library for Laravel (Comment implementuje HasMedia). Obrázky dostanú responzívne varianty; ostatné súbory sa ukladajú ako originály a servírujú cez podpísaný streaming:
$media = $comment->addMedia($request->file('file'))
->toBucket($comment->attachmentsBucket());
$comment->attachments(); // Collection<Media>
$comment->hasAttachments(); // bool
$comment->attachmentUrls(); // list<string>, each resolved by its visibility
$comment->attachmentUrls('responsive-320'); // that variant where generated, else the original
$comment->resolveAttachmentUrl($media); // public URL if public, signed short-lived URL if private
$comment->attachmentUrl($media); // always a signed, short-lived URL
$comment->clearMediaBucket($comment->attachmentsBucket()); // remove every attachmentVarianty obrázkov
Obrázkové prílohy dostanú jeden vygenerovaný variant pre každú responzívnu šírku s názvom responsive-<šírka> — podľa comments.media.responsive_widths, inak podľa rebríka media.responsive.widths z Media Library (predvolene 320, 640, 960, 1280, 1920); generujú sa len šírky, ktoré obrázok dokáže vyplniť. Variant, ktorý príloha nemá — každý súbor, ktorý nie je obrázkom, alebo názov, ktorý skupina nikdy negeneruje — sa nahradí originálom, takže attachmentUrls($variant) nad zmiešanými prílohami nikdy nevyhodí výnimku.
Súkromné a verejné prílohy
Prílohy sú predvolene súkromné (comments.media.visibility). Na súkromnú prílohu vedie vždy len podpísaný krátkodobý odkaz — na diskoch typu S3 natívne podpísaný, inak cez podpísanú streamovaciu routu Media Library. attachmentUrls(), vložené médiá v renderBody() aj CommentResource určujú URL každej prílohy podľa jej vlastnej viditeľnosti cez resolveAttachmentUrl(), takže súkromná príloha verejnú URL nikdy nedostane. Platnosť určuje comments.media.temporary_url_lifetime, inak platí predvolená hodnota Media Library.
Podpísané URL chránia odkaz, preto bajty nesmú byť dostupné inou cestou. Ak comments.media.disk nie je nastavený, súkromné prílohy aj ich varianty idú na comments.media.private_disk — predvolene disk local v Laraveli (storage/app/private) — nikdy nie na verejný disk, ktorý sprístupňuje php artisan storage:link. COMMENTS_MEDIA_PRIVATE_DISK môžete nasmerovať na iný neverejný disk; disk nastavený v COMMENTS_MEDIA_DISK sa použije pre všetky prílohy, preto ho pri súkromných prílohách nechajte neverejný:
// config/comments.php — where attachment bytes live
'media' => [
'visibility' => 'private', // the default: every link is signed and short-lived
'disk' => null, // null = by visibility (private → private_disk, public → media default)
'private_disk' => 'local', // storage/app/private — never the public disk
'temporary_url_lifetime' => 10, // minutes; null = the Media Library default
],Obmedzenia skupiny
Skupinu zúžite cez konfiguráciu — disk, allowlist mime typov, maximálnu veľkosť a rebrík responzívnych šírok:
// config/comments.php
'media' => [
'attachments_bucket' => 'attachments',
'visibility' => 'public',
'disk' => 's3', // used for every attachment when set
'accepted_mime_types' => ['image/jpeg', 'image/png', 'application/pdf'],
'max_file_size' => 2 * 1024 * 1024, // bytes — enforced on upload
'responsive_widths' => [320, 640, 960],
'temporary_url_lifetime' => 10, // minutes
'inline' => [
'enabled' => true,
'default_variant' => '',
'on_missing' => 'strip',
],
],Nahrávané súbory sa kontrolujú voči skupine hneď pri vstupe: accepted_mime_types a max_file_size (v bajtoch) spôsobia, že Media Library súbor odmietne výnimkou FileUnacceptableForBucket.
Vložené médiá
Prílohy vložíte do textu ako na GitHube či Reddite tokenmi [media:UUID] alebo [media:UUID|variant]. renderBody() ich hľadá len v skupine samotného komentára — nikdy v ľubovoľných globálnych médiách — jedným dávkovým dotazom a nikdy nevyhodí výnimku pri chýbajúcom UUID ani pri variante, ktorý obrázok nemá:
$comment->update(['comment' => "see this [media:{$media->uuid}]"]);
$comment->update(['comment' => "a fixed width [media:{$media->uuid}|responsive-320]"]);
echo $comment->renderBody(); // HtmlString: responsive <img> for images, <a> for other files
// Safe with user input: escape the text when you write it — tokens survive e()
Comments::on($post)->as($user)->body(e($request->input('body')))->post();- Obrázky sa vykreslia ako responzívny <img> so srcset; s variantom (v tokene alebo cez default_variant) ako obyčajný <img> daného variantu — variant, ktorý obrázok nemá, sa vykreslí ako responzívny <img>.
- Ostatné súbory sa vykreslia ako odkaz <a> s názvom súboru.
- Nenájdené tokeny sa odstránia, alebo s on_missing => 'keep' ponechajú; chybne zapísané tokeny zostanú nedotknuté.
- S inline.enabled => false vráti renderBody() pôvodné telo.
Bezpečnosť: renderBody() text neescapuje
Escapujú sa len vygenerované značky <img> a <a>; všetko okolo tokenov sa vráti presne tak, ako je uložené. Keďže renderBody() vracia HtmlString, Blade ho vypíše surovo aj vnútri {{ }}. Pri obyčajnom texte vypíšte atribút comment a escapovanie nechajte na Blade. Pri texte s vloženými médiami escapujte text už pri zápise — tokeny neobsahujú špeciálne HTML znaky, takže e() prežijú — alebo výstup preveďte cez HTML sanitizér, ktorý povolí len vygenerované značky.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.