PHP code example of elegantly / laravel-media

1. Go to this page and download the library: Download elegantly/laravel-media 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/ */

    

elegantly / laravel-media example snippets


use Elegantly\Media\Jobs\DeleteModelMediaJob;
use Elegantly\Media\Models\Media;

return [
    /**
     * The media model
     * Define your own model here by extending \Elegantly\Media\Models\Media::class
     */
    'model' => Media::class,

    /**
     * The path used to store temporary file copy for conversions
     * This will be used with storage_path() function
     */
    'temporary_storage_path' => 'app/tmp/media',

    /**
     * The default disk used for storing files
     */
    'disk' => env('MEDIA_DISK', env('FILESYSTEM_DISK', 'local')),

    /**
     * Determine if media should be deleted with the model
     * when using the HasMedia Trait
     */
    'delete_media_with_model' => true,

    /**
     * Determine if media should be deleted with the model
     * when it is soft deleted
     */
    'delete_media_with_trashed_model' => false,

    /**
     * Deleting a large number of media attached to a model can be time-consuming
     * or even fail (e.g., cloud API error, permissions, etc.)
     * For performance and monitoring, when a model with the HasMedia trait is deleted,
     * each media is individually deleted inside a job.
     */
    'delete_media_with_model_job' => DeleteModelMediaJob::class,

    /**
     * The default collection name
     */
    'default_collection_name' => 'default',

    /**
     * Prefix for the generated path of files
     * Set to null if you do not want any prefix
     * To fully customize the generated default path, extend the Media model and override the generateBasePath method
     */
    'generated_path_prefix' => null,

    /**
     * Customize the queue connection used when dispatching conversion jobs
     */
    'queue_connection' => env('QUEUE_CONNECTION', 'sync'),

    /**
     * Customize the queue used when dispatching conversion jobs
     * null will fall back to the default Laravel queue
     */
    'queue' => null,

];

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Elegantly\Media\Concerns\HasMedia;
use Elegantly\Media\Contracts\InteractWithMedia;
use Elegantly\Media\MediaCollection;

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

    public function registerMediaCollections(): array;
    {
        return [
            new MediaCollection(
                name: 'avatar',
                single: true, // If true, only the latest file will be kept
                disk: 's3', // (optional) Specify where the file will be stored
                acceptedMimeTypes: [ // (optional) Specify accepted file types
                    'image/jpeg',
                    'image/png',
                    'image/webp'
                ]
            )
        ];
    }
}

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Elegantly\Media\Concerns\HasMedia;
use Elegantly\Media\Contracts\InteractWithMedia;
use Elegantly\Media\MediaCollection;
use Elegantly\Media\MediaConversionDefinition;
use Elegantly\Media\Converters\MediaMp4Converter;
use Elegantly\Media\Converters\MediaFrameConverter;
use Elegantly\Media\Converters\MediaImageConverter;

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

    public function registerMediaCollections(): array;
    {
        return [
            new MediaCollection(
                name: 'videos',
                conversions: [
                    new MediaConversionDefinition(
                        name: 'poster',
                        converter: fn ($media) => new MediaFrameConverter(
                            media: $media,
                            filename: "{$media->name}-thumbnail.jpg",
                            timecode: 0,
                        ),
                        conversions: [
                            new MediaConversionDefinition(
                                name: '360p',
                                converter: fn ($media) => new MediaImageConverter(
                                    media: $media,
                                    filename: "{$media->name}.jpg"
                                    width: 360
                                )
                            ),
                        ],
                    ),
                    new MediaConversionDefinition(
                        name: '720p',
                        converter: fn ($media) => new MediaMp4Converter(
                            media: $media,
                            filename: "{$media->name}.mp4"
                            width: 720
                        )
                    ),
                ]
            )
        ];
    }
}

use Elegantly\Media\Exceptions\InvalidMimeTypeException;

public function store(Request $request, Channel $channel)
{
    try {
        $channel->addMedia(
            file: $request->file('avatar'),
            collectionName: 'avatar',
            name: "{$channel->name}-avatar"
        );
    } catch (InvalidMimeTypeException $exception){
        // Will throw an error if the mime type is not 

use Livewire\WithFileUploads;
use Elegantly\Media\Exceptions\InvalidMimeTypeException;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;

class ImageUploader extends Component
{
    use WithFileUploads;

    /** @var ?TemporaryUploadedFile */
    public $avatar = null;

    public function save()
    {
        try {
            $this->channel->addMedia(
                file: $this->avatar->getRealPath(),
                collectionName: 'avatar',
                name: "{$this->channel->name}-avatar"
            );
        } catch (InvalidMimeTypeException $exception){
            // Will throw an error if the mime type is not 

use Elegantly\Media\Exceptions\InvalidMimeTypeException;

 try {
    $channel->addMedia(
        file: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
        collectionName: 'videos',
        name: "BigBuckBunny"
    );
} catch (InvalidMimeTypeException $exception){
    // Will throw an error if the mime type is not 

// Get all media from a specific collection
$avatars = $channel->getMedia('avatar');

// Get the first media from a collection
$avatar = $channel->getFirstMedia('avatar');

// Check if media exists
$hasAvatar = $channel->hasMedia('avatar');

$media = $channel->getFirstMedia('avatar');

// File properties
$media->name; // file_name without the extension
$media->file_name;
$media->extension;
$media->mime_type;
$media->size; // in bytes
$media->humanReadableSize();

// Image/Video specific properties
$media->width;       // in pixels
$media->height;      // in pixels
$media->aspect_ratio;
$media->duration;    // for video/audio

// Get the original media URL
$originalUrl = $media->getUrl();

// Get a specific conversion URL
$thumbnailUrl = $media->getUrl(
    conversion: '360p',
    fallback: true // Falls back to original if conversion doesn't exist
);

$posterUrl = $media->getUrl(
    conversion: 'poster.360p',
    fallback: 'poster' // Falls back to an other conversion doesn't exist
);

// Use the same logic with other properties such as
$media->getPath();
$media->getWith();
// ...

// Check if a conversion exists
$hasThumbnail = $media->hasConversion('100p');

// Get a specific conversion
$thumbnailConversion = $media->getConversion('100p');

// Get the 'poster' conversion
$media->getParentConversion('poster.360p');

// Only get children conversions of poster
$media->getChildrenConversions('poster');

new MediaCollection(
    name: 'avatar',
    conversions: [
        new MediaConversionDefinition(
            name: '360p',
            queued: true,  // (default) Dispatch as a background job
            queue: 'slow' // (optional) Specify a custom queue
            converter: fn ($media) => new MediaImageConverter(
                media: $media,
                filename: "{$media->name}.jpg"
                width: 360
            )
        ),
        new MediaConversionDefinition(
            name: '180p',
            queued: false,  // Generate the conversion synchronously
            converter: fn ($media) => new MediaImageConverter(
                media: $media,
                filename: "{$media->name}.jpg"
                width: 180
            )
        ),
    ]
)

new MediaCollection(
    name: 'avatar',
    conversions: [
        new MediaConversionDefinition(
            name: '360p',
            immediate: false, // Conversion will not be generated at upload time
            converter: fn ($media) => new MediaImageConverter(
                media: $media,
                filename: "{$media->name}.jpg"
                width: 360
            )
        ),
        new MediaConversionImage(
            name: '360',
            width: 360,
        )
    ]
)

// Generate the conversion synchronously
$media->executeConversion(
    conversion: '360',
    force: false // Skips execution if the conversion already exists
);

// Dispatch the conversion as a background job
$media->dispatchConversion(
    conversion: '360',
    force: false // Skips execution if the conversion already exists
);

new MediaCollection(
    name: 'avatar',
    onAdded: function ($media) {
        // Example: Notify the model when new media is added
        // $media->model->notify(new MediaAddedNotification($media));
    }
);

new MediaConversionImage(
    name: '360',
    onCompleted: function ($conversion, $media, $parent) {
        // Example: Refresh your UI
        // broadcast(new MyEvent($media));
    }
);

namespace App\Media\Converters\Image;

use Elegantly\Media\Converters\MediaConverter;
use Elegantly\Media\Enums\MediaType;
use Elegantly\Media\Models\Media;
use Elegantly\Media\Models\MediaConversion;
use Illuminate\Contracts\Filesystem\Filesystem;
use Spatie\Image\Enums\Fit;
use Spatie\Image\Image;
use Spatie\ImageOptimizer\OptimizerChain;
use Spatie\TemporaryDirectory\TemporaryDirectory as SpatieTemporaryDirectory;

class MediaImageConverter extends MediaConverter
{
    public function __construct(
        public readonly Media $media,
        public string $filename,
        public ?int $width = null,
        public ?int $height = null,
        public Fit $fit = Fit::Max,
        public ?OptimizerChain $optimizerChain = null,
    ) {}

    public function shouldExecute(Media $media, ?MediaConversion $parent): bool
    {
        $source = $parent ?? $media;

        return $source->type === MediaType::Image;
    }

    public function convert(
        Media $media,
        ?MediaConversion $parent,
        ?string $file,
        Filesystem $filesystem,
        SpatieTemporaryDirectory $temporaryDirectory
    ): ?MediaConversion {

        if (! $file) {
            return null;
        }

        $input = $filesystem->path($file);
        $output = $filesystem->path($this->filename);

        Image::load($input)
            ->fit($this->fit, $this->width, $this->height)
            ->optimize($this->optimizerChain)
            ->save($output);

        return $media->addConversion(
            file: $output,
            conversionName: $this->conversion,
            parent: $parent,
        );

    }
}

// Store a new file as a conversion
$media->addConversion(
    file: $file, // Can be an HTTP File, URL, or file path
    conversionName: 'transcript',
    parent: $mediaConversion // (Optional) Specify a parent conversion
    // Additional parameters...
);

// Replace an existing conversion safely
// If the same conversion already exists, it ensures the new file is stored before deleting the previous one.
$media->replaceConversion(
    conversion: $mediaConversion
);

// Safely delete a specific conversion and all its children
$media->deleteConversion('360');

// Safely delete only the child conversions of a parent conversion
$media->deleteChildrenConversions('poster');

// Dispatch or execute a conversion
$media->dispatchConversion('360'); // Runs asynchronously as a job
$media->executeConversion('poster.360'); // Executes synchronously
$media->getOrExecuteConversion('poster.360'); // Retrieves or generates the conversion

// Retrieve conversion information
$media->getConversion('360'); // Fetch a specific conversion
$media->hasConversion('360'); // Check if a conversion exists
$media->getParentConversion('poster.360'); // Retrieve the parent (poster) of a conversion
$media->getChildrenConversions('poster'); // Retrieve child conversions

use \Elegantly\Media\UrlFormatters\CloudflareImageUrlFormatter;

// Default formatter (query parameters)
$default = $media->getUrl(
    parameters: ['width' => 360],
); // https://your-url.com?width=360

// Cloudflare formatter (path-based format)
$cloudflare = $media->getUrl(
    parameters: ['width' => 360],
    formatter: CloudflareImageUrlFormatter::class
); // /cdn-cgi/media/width=360/https://your-url.com

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Elegantly\Media\Concerns\HasMedia;
use Elegantly\Media\Contracts\InteractWithMedia;
use Elegantly\Media\MediaCollection;
use Elegantly\Media\MediaConversionDefinition;
use Elegantly\Media\Converters\MediaImagePlaceholderConverter;

class User extends Model implements InteractWithMedia
{
    use HasMedia;

    public function registerMediaCollections(): array;
    {
        return [
            new MediaCollection(
                name: 'avatar',
                single: true,
                conversions: [
                    new MediaConversionDefinition(
                        name: 'placeholder',
                        converter: fn ($media) => new MediaImagePlaceholderConverter($media),
                    ),
                ]
            )
        ];
    }
}

$placeholder = $media->getConversion('placeholder');

$base64Image = $placeholder?->contents;

namespace App\Models;

use Elegantly\Media\Models\Media as ElegantlyMedia;

class Media extends ElegantlyMedia
{
    // ...
}

use App\Models\Media;

return [

    'model' => Media::class,

    // ...

];

namespace App\Models;

use App\Models\Media;
use Elegantly\Media\Concerns\HasMedia;
use Elegantly\Media\Contracts\InteractWithMedia;

/**
 * @implements InteractWithMedia<Media>
 */
class Post extends Model implements InteractWithMedia
{
    /** @use HasMedia<Media> **/
    use HasMedia;

    // ...
}
bash
php artisan vendor:publish --tag="media-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="media-config"
bash
php artisan vendor:publish --tag="media-views"
bash
php artisan media:generate-conversions
bash
php artisan media-conversions:retry