DEV Community

Daniyal Javani
Daniyal Javani

Posted on • Edited on

7

Temporary URL for local driver in Spatie Laravel media library

Today’s guide describes the implementation of temporary URL for local driver in spatie/laravel-medialibrary. We'll accomplish this via Laravel signed URLs.

If you use getTemporaryUrl() function of the laravel-medialibrary for local driver, you will get the following error:
RuntimeException with message 'This driver does not support creating temporary URLs.'

The below steps describe how to implement getTemporaryUrl function in your Laravel app.

Step 1: Add a private disk to config file

Laravel already comes with local, public and s3 disks and you should add your own disk for private files to config/filesystems.

/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
*/

'disks' => [
    'private' => [
        'driver' => 'local',
        'root' => storage_path('app/private'),
        'url' => env('APP_URL').'/private-storage',
        'visibility' => 'private',
    ],
],
Enter fullscreen mode Exit fullscreen mode

Step 2: Add files to the private disk

You must ensure that files added to secret-files collection are automatically added to the private disk.

// in your model

public function registerMediaCollections(): void
{
    $this
       ->addMediaCollection('secret-files')
       ->useDisk('private');
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create a controller that handle file requests

It does nothing but returning the media model instance.
Note: You can even authorise using Laravel policy.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Storage;

class ServePrivateStorage extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Media $media)
    {
        // $this->authorize('view', $media->model);

        return $media;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the controller's signed route

Route::get('private-storage/{media}/{filename}', 'ServePrivateStorage')
    ->middleware('signed')
    ->name('private-storage');
Enter fullscreen mode Exit fullscreen mode

Step 5: Now we need a media URL generator class

In this step we extend the DefaultUrlGenerator and override the getTemporaryUrl function.

namespace App\Services;

use DateTimeInterface;
use Illuminate\Support\Facades\URL;
use Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator;

class MediaUrlGeneratorService extends DefaultUrlGenerator
{
    public function getTemporaryUrl(DateTimeInterface $expiration, array $options = []): string
    {
        return URL::temporarySignedRoute(
            'private-storage',
            $expiration,
            ['media' => $this->media, 'filename' => $this->media]
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Replace your URL generator with the default one

Open the config/media-library.php file and replace the following class with yours.

'url_generator' => Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class,
Enter fullscreen mode Exit fullscreen mode



That's it. Now your local driver does support creating temporary URLs.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (2)

Collapse
 
gasparotto30 profile image
gasparotto30

Thank you very much!!

Collapse
 
mojtabad profile image
Mojtaba Darvishi

Thank you Daniyal! Very helpful

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs