PHP code example of risetechapps / media-for-laravel

1. Go to this page and download the library: Download risetechapps/media-for-laravel library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

risetechapps / media-for-laravel example snippets


use Illuminate\Database\Eloquent\Model;
use RiseTechApps\Media\Contracts\MediaContract;
use RiseTechApps\Media\Traits\InteractsWithMedia\InteractsWithMedia;
use RiseTechApps\Media\Support\Collections\MediaCollection;
use RiseTechApps\Media\Support\Conversions\Conversion;
use Spatie\Image\Enums\Fit;

class Client extends Model implements MediaContract
{
    use InteractsWithMedia;

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('avatar')
            ->singleFile()
            ->acceptsMimeTypes(['image/jpeg', 'image/png', 'image/webp'])
            ->useFallbackUrl('/img/sem-foto.png');

        $this->addMediaCollection('documentos');
    }

    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('thumb')
            ->fit(Fit::Crop, 368, 232)
            ->format('webp')
            ->quality(80)
            ->optimize()
            ->orientation()
            ->queued();
    }
}

use RiseTechApps\Media\Contracts\MediaContract;
use RiseTechApps\Media\Traits\HasMediaSuite\HasMediaSuite;

class Client extends Model implements MediaContract
{
    use HasMediaSuite;
}

class Client extends Model implements MediaContract
{
    use HasMediaSuite;

    // Adiciona sem perder os defaults:
    protected function additionalMediaCollections(): void
    {
        $this->addMediaCollection('documentos')->singleFile();
    }

    protected function additionalMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('preview')->width(1024)->queued();
    }

    // Ou ajusta um default pontual:
    protected function defaultConversionFormat(): string { return 'png'; }
}

// De um UploadedFile, caminho local ou RemoteFile
$client->addMedia($request->file('foto'))->toMediaCollection('avatar');

// Direto do request
$client->addMediaFromRequest('foto')->toMediaCollection('avatar');

// De um disco já existente
$client->addMediaFromDisk('caminho/arquivo.pdf', 's3')->toMediaCollection('documentos');

// De uma URL (streaming, com proteção contra SSRF — ver abaixo)
$client->addMediaFromUrl('https://exemplo.com/foto.jpg')->toMediaCollection('avatar');

$client->addMedia($file)
    ->usingName('Contrato 2026')
    ->usingFileName('contrato.pdf')
    ->withCustomProperties(['origem' => 'importacao'])
    ->withProperty('lote', 42)
    ->preservingOriginal()                 // não remove a origem
    ->storingConversionsOnDisk('s3')
    ->withResponsiveImages()
    ->toMediaCollection('documentos', 's3'); // (coleção, disco)

$client->getMedia('documentos');                    // Collection<Media>
$client->getFirstMedia('avatar');                   // ?Media
$client->hasMedia('avatar');                        // bool
$client->getFirstMediaUrl('avatar', 'thumb');       // string (fallback se vazio)
$client->getFirstMediaPath('avatar');               // ?string

$media = $client->getFirstMedia('avatar');
$media->getUrl('thumb');            // URL crua do disco
$media->getFullUrl('thumb');        // URL de exibição (S3 assinada + cache)
$media->getTemporaryUrl(now()->addHour(), 'thumb');
$media->total_size;                 // bytes reais (original + derivados)

$client->clearMediaCollection('documentos');
$client->clearMediaCollectionExcept('documentos', $mediaParaManter);
$client->deleteAllMedia();

// Opt-in por coleção
$this->addMediaCollection('fotos')->withResponsiveImages();

$media->getSrcset();       // "url-1024.jpg 1024w, url-768.jpg 768w, ..."
$media->getSrcsetArray();  // [['width'=>1024,'url'=>'...'], ...]
$media->hasResponsiveImages();

'url_generator' => App\Media\CdnUrlGenerator::class,

use RiseTechApps\Media\MediaFacade as Media;

Media::storage()->total();               // bytes de tudo
Media::storage()->byCollection();        // ['avatar' => 1234, ...]
Media::storage()->byModelType();         // ['App\Models\Client' => ...]
Media::storage()->forModel($client);     // bytes de um dono
Media::storage()->forModel($client, 'avatar');
Media::storage()->forModelByCollection($client);
Media::storage()->forModelType(Client::class);
Media::storage()->humanize(1536);        // "1.5 KB"

$client->mediaStorageUsage();            // total do dono
$client->mediaStorageUsage('avatar');    // só a coleção
$client->mediaStorageByCollection();     // quebrado por coleção

Media::storage()->total(false);

use RiseTechApps\Media\Support\Reports\Size;

Size::of($bytes)->gb();          // 2.34
Size::of($bytes)->mb(1);         // 2396.4  (1 casa)
Size::of($bytes)->forHumans();   // "2.3 GB" (unidade automática)
(string) Size::of($bytes);       // "2.3 GB"

Size::parse('10GB');             // 10737418240
Size::parse('500 MB');           // 524288000

use RiseTechApps\Media\Contracts\MediaScopeResolver;

class TenancyMediaScope implements MediaScopeResolver
{
    public function resolve(): array
    {
        return SubTenant::current()
            ? ['sub_tenant_id' => SubTenant::current()->id]
            : [];   // [] = sem contexto (fail-closed)
    }
}

// config/media.php
'scope' => ['resolver' => App\Media\TenancyMediaScope::class],

// ou em runtime:
Media::resolveScopeUsing(fn () => ['sub_tenant_id' => 42]);

use RiseTechApps\Media\Models\Media as MediaModel;

MediaModel::unscoped()->get();

use RiseTechApps\Media\Contracts\QuotaResolver;

class PlanQuota implements QuotaResolver
{
    public function limitInBytes(): ?int
    {
        return SubTenant::current()?->plan->storage_bytes; // null = ilimitado
    }
}

'quota' => ['resolver' => App\Media\PlanQuota::class],

'quota' => ['default' => '10GB'], // ou 10737418240; null = ilimitado

Media::quota()->usage();              // bytes usados no contexto
Media::quota()->limit();              // ?int
Media::quota()->remaining();          // ?int
Media::quota()->exceeded();           // bool
Media::quota()->percentUsed();        // float (pode passar de 100)
Media::quota()->percentUsed(clamp: true); // teto 100 p/ barra de progresso
Media::quota()->usageSize()->gb();
Media::quota()->remainingSize()?->forHumans() ?? 'ilimitado';

use RiseTechApps\Media\Exceptions\StorageQuotaExceeded;

try {
    $client->addMedia($file)->toMediaCollection('documentos');
} catch (StorageQuotaExceeded $e) {
    // $e->limit, $e->usage, $e->attempted (bytes)
    return response()->json(['erro' => 'Cota de armazenamento excedida'], 413);
}

use RiseTechApps\Media\MediaFacade as Media;

Media::routes(['middleware' => ['auth:sanctum']]);
// expõe POST /uploads → cria um upload temporário e devolve o recurso

Media::syncUploads($client, $uploadIds, 'documentos');    // em fila
Media::syncUploadsNow($client, $uploadIds, 'documentos'); // imediato

// config/media.php
'prune' => [
    'enabled' => true,     // MEDIA_PRUNE_ENABLED
    'time'    => '02:00',  // MEDIA_PRUNE_TIME
],

// exemplo — dentro do loop por tenant do seu tenancy
Artisan::call('model:prune', ['--model' => [
    \RiseTechApps\Media\Models\Media::class,
    \RiseTechApps\Media\Models\MediaUploadTemporary::class,
]]);
bash
composer migrate
bash
php artisan vendor:publish --tag=config
bash
composer update risetechapps/media-for-laravel
php artisan migrate
php artisan media:reconcile        # opcional — ver abaixo
bash
php artisan media:reconcile --dry-run       # mostra o que seria registrado
php artisan media:reconcile                 # grava
php artisan media:reconcile --media=<uuid>  # apenas uma mídia
cron
* * * * * cd /caminho && php artisan schedule:run >> /dev/null 2>&1