NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Media Library for Laravel

Fasáda MediaLibrary

Všetko ide cez jednu fasádu, RoundlyConsulting\MediaLibrary\Facades\MediaLibrary. Ploché metódy add* začínajú globálne pridanie, for($model) obmedzí pridávanie a čítanie na jedného vlastníka, ploché slovesá pracujú s médiom, ktoré im odovzdáte, a variants($media) združuje operácie s variantmi:

use RoundlyConsulting\MediaLibrary\Facades\MediaLibrary;

// Owner-scoped: add, read and delete one model's media
MediaLibrary::for($user)->add($request->file('avatar'))->toBucket('avatar');
MediaLibrary::for($user)->first('avatar');

// Global (no owner)
MediaLibrary::add(storage_path('brand/logo.svg'))->toBucket('brand');

// Flat verbs act on the media you hand them
MediaLibrary::move($media, to: $otherUser, bucket: 'gallery');
MediaLibrary::replace($media, $request->file('avatar'));
MediaLibrary::delete($media);

// Variant operations for one media
MediaLibrary::variants($media)->missing();

Ploché metódy

MetódaVraciaČo robí
add($file), addFromUrl(), addFromDisk(), addFromString(), addFromBase64(), addFromStream()PendingFileAddZačne globálne pridanie (bez vlastníka).
draft($file)PendingFileAddZačne globálne pridanie draftu.
for($model)ModelMediaHandle viazaný na vlastníka — pridanie, drafty, attach, čítanie, clear a delete pre jeden model.
attach($media, to: ?Model, bucket:)MediaPripojí referenciou (bez kopírovania bajtov); to: null = globálna skupina.
bindDraft($token, to: $model, bucket:)MediaNaviaže draft na vlastníka — uplatnia sa pravidlá, úložisko, pravidlo jedného súboru aj varianty skupiny.
move($media, to: ?Model, bucket:, disk:)MediaPresunie k inému vlastníkovi a/alebo na iný disk.
moveToDisk($media, $disk) / moveVariantsToDisk($media, $disk)MediaPresunie súbory, alebo len varianty, na iný disk.
copy($media, to: ?Model, bucket:, disk:)MediaSkopíruje do nového riadku (nové uuid).
replace($media, $file)MediaNové bajty, rovnaké id/uuid (aj URL, pokiaľ starý súbor nie je zdieľaný).
delete($media)voidZmaže riadok aj súbory (strážené refcountom).
variants($media)MediaVariantsall(), generated(), missing(), regenerate(only:, force:).
regenerate($media, only: [], force: false)list<string>Prekreslí varianty; vráti názvy vykreslených.
pruneDrafts()intZmaže expirované, nikdy nenaviazané drafty.
rulesFor(Model::class, $bucket)list<string>Validačné pravidlá z definície skupiny.
bucket($bucket) / find($uuid) / clearBucket($bucket)Builder / ?Media / intGlobálne čítanie a vyprázdnenie.

Handle for($model)

MediaLibrary::for($model) vráti handle ModelMedia. Jeho rozsah je bezpečnostná hranica: find() vráti null a delete() vyhodí MediaDoesNotBelongToModel pre médium, ktoré je globálne alebo patrí inému modelu — kontrolér teda môže bezpečne volať MediaLibrary::for($request->user())->find($uuid).

MetódaVraciaČo robí
add(), addFromRequest(), addFromUrl(), addFromDisk(), addFromString(), addFromBase64(), addFromStream()PendingFileAddPridanie pre vlastníka; addFromRequest() vyhodí FileDoesNotExist, ak kľúč nemá upload.
bindDraft($token, $bucket)MediaNaviaže draft na tento model.
attach($media, $bucket)MediaPripojí existujúce médium referenciou.
get($bucket) / first($bucket) / has($bucket)Collection / ?Media / boolČítanie skupiny v poradí.
find($uuid)?MediaLen médiá, ktoré tento model vlastní — inak null.
url($bucket, $variant) / temporaryUrl($bucket, $variant, $expiry)stringURL prvého média, inak fallback skupiny, inak prázdny reťazec.
clear($bucket)intZmaže všetky médiá v skupine.
delete($media)voidPre globálne alebo cudzie médium vyhodí MediaDoesNotBelongToModel.

Presun, kópia a mazanie

Médium aj jeho varianty sa dajú presunúť na iný disk alebo k inému modelu a skupine — aj z modelu do globálnej skupiny a späť. Presun medzi diskami bajty streamuje a zápis do databázy beží v transakcii; zdrojové súbory sa odstránia až po jej potvrdení:

// Move the original (and same-disk variants) to another disk.
MediaLibrary::moveToDisk($media, 'cold');

// Move only the variant files to another disk; the original stays put.
MediaLibrary::moveVariantsToDisk($media, 'hot');

// Re-home to a different model and bucket (deletes the source files).
MediaLibrary::move($media, to: $otherUser, bucket: 'gallery');

// Move a model's media to global storage (no owner).
MediaLibrary::move($media, to: null, bucket: 'brand');

// Copy instead of move: a new row with a fresh UUID, source preserved.
$copy = MediaLibrary::copy($media, to: $otherUser, bucket: 'gallery', disk: 'cold');

// Permanently delete the row and its files (refcount-guarded).
MediaLibrary::delete($media);

// The same verbs on the model:
$media->moveToDisk('cold');
$media->move($otherUser, 'gallery');
$copy = $media->copy($otherUser, 'gallery', 'cold');
$media->deleteWithFiles();

Presun či kópia k inému vlastníkovi alebo do inej skupiny uplatní cieľovú skupinu: najprv overí jej pravidlá prijatia (FileUnacceptableForBucket), vynúti jej pravidlo jedného súboru, varianty, ktoré nedefinuje, zahodí a tie, ktoré definuje a médiu chýbajú, vygeneruje. Varianty definované v oboch skupinách sa ponechajú — ak sa líšia, spustite MediaLibrary::regenerate($media, force: true). Presun zachová disk a viditeľnosť média, pokiaľ nezadáte disk:. Na tom istom disku kópia odkazuje na uložený originál zdroja (bez kopírovania bajtov, strážené refcountom); na inom disku sa originál skopíruje.

Presun spustí MediaHasBeenMoved, kópia spustí MediaHasBeenAdded pre nový riadok. Bežné Eloquent delete() je soft delete a súbory ponechá, aby obnovenie nič nestratilo — odstráni ich len MediaLibrary::delete() (alebo deleteWithFiles(), prípadne force delete), ktoré spustí MediaHasBeenDeleted.

Drafty — nahratie skôr, než model existuje

Draft je bežný riadok média bez vlastníka, s vygenerovaným draft_token a platnosťou (media.drafts.ttl, predvolene 24 hodín). Rozmery a náhľady sa vypočítajú už pri nahratí. Skupina je známa až pri naviazaní, preto sa uplatní práve vtedy: overia sa jej pravidlá prijatia (FileUnacceptableForBucket nechá draft nenaviazaný), originál sa presunie na disk a do viditeľnosti, ktoré skupina deklaruje, predošlé médium skupiny so singleFile() sa zmaže a vygenerujú sa varianty skupiny:

use RoundlyConsulting\MediaLibrary\Facades\MediaLibrary;

// Upload step — no model yet. Hand the token back to the client.
$draft = MediaLibrary::draft($request->file('avatar'))->toBucket('avatar');
$token = $draft->draft_token;

// When the form is submitted and the model is saved, bind by token:
MediaLibrary::for($user)->bindDraft($token, 'avatar');   // sets the owner, clears the token
// …or the flat verb, or the trait shorthand:
MediaLibrary::bindDraft($token, to: $user, bucket: 'avatar');
$user->attachDraftMedia($token, 'avatar');

// Delete expired, never-bound drafts (or schedule media:prune-drafts):
MediaLibrary::pruneDrafts();                             // returns the count

Naviazanie vyhodí DraftMediaNotFound (neznámy alebo už použitý token) alebo DraftMediaExpired (po uplynutí platnosti); úspešné naviazanie spustí DraftMediaHasBeenBound. Nenaviazané drafty nie sú globálne médiá: MediaLibrary::bucket(), clearBucket() ani media:clear "" sa ich nedotknú a $hidden modelu drží draft_token mimo serializovaného výstupu — čítajte ho ako vlastnosť.

Pripojenie referenciou a náhrada na mieste

attach() pripojí existujúce médium k modelu bez opätovného nahrávania — nový riadok zdieľa ten istý uložený originál, neskopíruje sa ani bajt a varianty cieľovej skupiny sa vygenerujú nanovo. Platia pravidlá prijatia aj pravidlo jedného súboru cieľovej skupiny a náhrada zdroja nikdy nezmení bajty pripojeného riadku. replace() vymení bajty so zachovaním id aj uuid; nový súbor musí spĺňať skupinu vlastníka rovnako ako pri pridaní, metadáta a varianty sa prepočítajú a spustí sa MediaHasBeenReplaced:

$logo = MediaLibrary::bucket('brand')->first();

MediaLibrary::for($user)->attach($logo, 'avatar');         // new row, same file, no copy
MediaLibrary::attach($logo, bucket: 'shared');             // …or into another global bucket
$user->attachMedia($logo, 'avatar');                       // the trait shorthand

MediaLibrary::replace($media, $request->file('avatar'));   // same id/uuid/url, new bytes
$media->replace($request->file('avatar'));                 // the model shorthand

URL zostane rovnaká s dvoma výnimkami: keď sa nové bajty deduplikujú na iný uložený súbor a keď starý originál zdieľajú iné riadky (deduplikovaný upload, attach() či kópia na tom istom disku) — vtedy zostane pre ne nedotknutý a nové bajty pôjdu na vlastnú cestu tohto média.

Validačné pravidlá zo skupiny

Obmedzenia skupiny deklarujete raz a použijete v ľubovoľnom FormRequeste — zmeníte skupinu a pravidlá sa prispôsobia. Pravidlo vznikne len z deklarovaného obmedzenia (max je v kilobajtoch); skupina bez maxFileSize() použije media.max_file_size:

$this->addMediaBucket('avatar')
    ->acceptsMimeTypes(['image/jpeg', 'image/png', 'image/webp'])
    ->maxFileSize(5 * 1024 * 1024)   // bytes
    ->minDimensions(100, 100)
    ->maxDimensions(4096, 4096);

// In a FormRequest:
public function rules(): array
{
    return [
        'avatar' => MediaLibrary::rulesFor(User::class, 'avatar'),
        // ['file', 'mimetypes:image/jpeg,image/png,image/webp', 'max:5120',
        //  'dimensions:min_width=100,min_height=100,max_width=4096,max_height=4096']
    ];
}

Metódy modelu Media — move(), copy(), moveToDisk(), moveVariantsToDisk(), replace() a deleteWithFiles() — aj metódy traitu InteractsWithMedia sú len skratky, ktoré volajú tie isté slovesá manažéra. Všetko uvedené, vrátane MediaLibrary::fake(), teda platí aj pre ne.

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 kryptomien

Odoslaní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.