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


/avatar
  /avatar-360
/video
  /poster
    /poster-360
    /poster-720
  /360
  /720
  /1080
  /hls

namespace App\Models;

use Elegantly\Media\Traits\HasMedia;
use Elegantly\Media\MediaCollection;
use Elegantly\Media\MediaConversion;
use Elegantly\Media\Enums\MediaType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Spatie\Image\Enums\Fit;
use \App\Jobs\Media\OptimizedImageConversionJob;
use Elegantly\Media\Models\Media;
use Elegantly\Media\Contracts\InteractWithMedia;
use Illuminate\Contracts\Support\Arrayable;
use Elegantly\Media\Support\ResponsiveImagesConversionsPreset;

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

    public function registerMediaCollections(): Arrayable|iterable|null;
    {
       return [
            new MediaCollection(
                name: 'avatar',
                acceptedMimeTypes: [
                    'image/jpeg', 'image/png', 'image/gif', 'image/webp',
                ],
            )
            new MediaCollection(
                name: 'videos',
                acceptedMimeTypes: [
                    'video/mp4', 'video/webm', 'video/ogg', 'video/quicktime',
                ],
            )
       ];
    }

    public function registerMediaTransformations($media, UploadedFile|File $file): UploadedFile|File
    {
        if($media->collection_name === "avatar"){
            Image::load($file->getRealPath())
                ->fit(Fit::Crop, 500, 500)
                ->optimize()
                ->save();
        }

        return $file;
    }

    public function registerMediaConversions($media): Arrayable|iterable|null;
    {

        if($media->collection_name === 'avatar'){
            return [
                new MediaConversion(
                    conversionName: '360',
                    job: new OptimizedImageConversionJob(
                        media: $media,
                        width: 360,
                        fileName: "{$media->name}-360.jpg"
                    ),
                )
            ]
        }elseif($media->collection_name === 'videos'){
            return [
                new MediaConversion(
                    conversionName: 'poster',
                    sync: true,// The conversion will not be queued, you will have access to it immediatly
                    job: new VideoPosterConversionJob(
                        media: $media,
                        seconds: 1,
                        fileName: "{$media->name}-poster.jpg"
                    ),
                    conversions: function(GeneratedConversion $generatedConversion) use ($media){
                        return ResponsiveImagesConversionsPreset::make(
                            media: $media,
                            generatedConversion: $generatedConversion
                            widths: [360, 720]
                        )
                    }
                ),
                ...ResponsiveVideosConversionsPreset::make(
                    media: $media,
                    widths: [360, 720, 1080],
                )
            ]
        }

        return null;
    }
}

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ChannelAvatarController extends Controller
{
    function function store(Request $request, Channel $channel)
    {
        $channel->addMedia(
            file: $file->file('avatar'),
            collection_name: 'avatar',
            name: "{$channel->name}-avatar",
        )
    }
}

namespace App\Livewire;

use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Livewire\WithFileUploads;
use Livewire\Component;

class ImageUploader extends Component
{
    use WithFileUploads;

    function function save()
    {
        /** @var TemporaryUploadedFile */
        $file = $this->avatar;

        $this->channel->addMedia(
            file: $file->getRealPath(),
            collection_name: 'avatar',
            name: "{$channel->name}-avatar",
        )
    }
}

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 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,

    /**
     * Customize WithoutOverlapping middleware settings
     */
    'queue_overlapping' => [
        /**
         * The release value should be longer than the longest conversion job that might run
         * Default is: 1 minute. Increase it if your jobs are longer.
         */
        'release_after' => 60,
        /**
         * The expire value allows you to forget a lock in case of an unexpected job failure
         *
         * @see https://laravel.com/docs/10.x/queues#preventing-job-overlaps
         */
        'expire_after' => 60 * 60,
    ],

];

namespace App\Models;

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

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

}

namespace App\Models;

use Elegantly\Media\Traits\HasMedia;
use Elegantly\Media\MediaCollection;
use Illuminate\Database\Eloquent\Model;
use Elegantly\Media\Contracts\InteractWithMedia;
use Illuminate\Contracts\Support\Arrayable;

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

    public function registerMediaCollections(): Arrayable|iterable|null;
    {
       return [
            new MediaCollection(
                name: 'avatar',
                acceptedMimeTypes: [
                    'image/jpeg', 'image/png', 'image/gif', 'image/webp',
                ],
            )
            new MediaCollection(
                name: 'videos',
                acceptedMimeTypes: [
                    'video/mp4', 'video/webm', 'video/ogg', 'video/quicktime',
                ],
            )
       ];
    }
}

namespace App\Models;

use Elegantly\Media\Traits\HasMedia;
use Elegantly\Media\MediaCollection;
use Elegantly\Media\MediaConversion;
use Elegantly\Media\Enums\MediaType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Spatie\Image\Enums\Fit;
use \App\Jobs\Media\OptimizedImageConversionJob;
use Elegantly\Media\Models\Media;
use Elegantly\Media\Contracts\InteractWithMedia;
use Illuminate\Contracts\Support\Arrayable;
use Elegantly\Media\Support\ResponsiveImagesConversionsPreset;

class Channel extends Model implements InteractWithMedia
{
    use HasMedia;

    // ...

    public function registerMediaConversions($media): Arrayable|iterable|null;
    {

        if($media->collection_name === 'avatar'){
            return [
                new MediaConversion(
                    conversionName: '360',
                    job: new OptimizedImageConversionJob(
                        media: $media,
                        width: 360,
                        fileName: "{$media->name}-360.jpg"
                    ),
                )
            ]
        }elseif($media->collection_name === 'videos'){
            return [
                new MediaConversion(
                    conversionName: 'poster',
                    sync: true, // The conversion will not be queued, you will have access to it immediatly
                    job: new VideoPosterConversionJob(
                        media: $media,
                        seconds: 1,
                        fileName: "{$media->name}-poster.jpg"
                    ),
                    conversions: function(GeneratedConversion $generatedConversion) use ($media){
                        return ResponsiveImagesConversionsPreset::make(
                            media: $media,
                            generatedConversion: $generatedConversion
                            widths: [360, 720]
                        )
                    }
                ),
                ...ResponsiveVideosConversionsPreset::make(
                    media: $media,
                    widths: [360, 720, 1080],
                )
            ]
        }

        return null;
    }
}

namespace App\Support\MediaConversions;

use Elegantly\Media\Models\Media;
use Illuminate\Support\Facades\File;
use Spatie\Image\Enums\Fit;
use Spatie\Image\Image;
use Spatie\ImageOptimizer\OptimizerChain;
use Elegantly\Media\Jobs\MediaConversionJob;

class OptimizedImageConversionJob extends MediaConversionJob
{
    public string $fileName;

    public function __construct(
        public Media $media,
        ?string $queue = null,
        public ?int $width = null,
        public ?int $height = null,
        public Fit $fit = Fit::Contain,
        public ?OptimizerChain $optimizerChain = null,
        ?string $fileName = null,
    ) {
        parent::__construct($media, $queue);

        $this->fileName = $fileName ?? $this->media->file_name;
    }

    public function run(): void
    {
        $temporaryDisk = $this->getTemporaryDisk();
        $path = $this->makeTemporaryFileCopy();

        $newPath = $temporaryDisk->path($this->fileName);

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

        $this->media->storeConversion(
            file: $newPath,
            conversion: $this->conversionName,
            name: File::name($this->fileName)
        );
    }
}

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\Traits\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="laravel-media-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="laravel-media-config"
bash
php artisan vendor:publish --tag="laravel-media-views"