Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Qlic's avatar
Level 18

DOMPDF and loading routed images

I'm using DOMPDF (Barry package) to generate .pdf files, for a new module i'm required to place images in the generated .pdf document. All my images are in the storage folder, and i use a route to return me the image i request.

The thing is, this images route is behind my auth route group, because only authenticated users are allowed to retrieve the images, but DOMPDF does not seem able to fetch the images. When i place the image route outside of the auth group, the images get loaded, but when i place it backinse the auth group they won't load.

Has anyone faced this issue aswell?

P.s. my auth group is a custom middleware, checking for a session called auth instead of the regular Laravel Auth::check() method.

Middleware:

public function handle($request, Closure $next, $guard = null)
{
    if (Session::has('auth')) {
        return $next($request);
    }

    return redirect()->route('login');
}

Routes:

Route::group(['middleware' => 'myMiddleware'], function() {

    Route::get('photo/{lead}/{type}/{name}/{plain?}',  ['as' => 'inventory.photo', function ($lead, $type, $name) {
        switch($type) {
            case 1:
                $folder = 'roof';
                break;
            case 2:
                $folder = 'meterboard';
                break;
            case 3:
                $folder = 'access';
                break;
            case 4:
                $folder = 'converter';
                break;
            case 5:
                $folder = 'cable';
                break;
        }

        return Image::make(storage_path() . '/app/photo/'. $lead .'/'. $folder .'/'. $name)->response();
    }]);
}]);

Controller:

public function workletter($link)
{
        return PDF::loadView('pdf.workletter', [
            'link' => $link
        ])->stream();
    }
}

Template:

{!! Html::image(route('inventory.photo', [$link]), 'Photo alt name') !!}
0 likes
14 replies
Qlic's avatar
Level 18

I added the code to make things more clear.

Qlic's avatar
Level 18

Absolutely nobody here that has an idea on how so tackle this? Or am i the only one to ever load an image from storage to a pdf through an auth route?

1 like
SaeedPrez's avatar
Level 50

@Qlic your problem is you put your code inside your route closure and attach middleware to it. Instead create a separate class or helper function that you can call from your route and your controller..

function getImage($foo, $bar, $whatever)
{
    // image getting code
    return $image;
}
Route::group(['middleware' => 'myMiddleware'], function() {

    Route::get('photo/{lead}/{type}/{name}/{plain?}',  ['as' => 'inventory.photo', function ($lead, $type, $name) {

        return getImage($foo, $bar, $whatever);

    }]);

}]);
{!! Html::image(route('inventory.photo', [getImage($foo, $bar, $whatever)]), 'Photo alt name') !!}

This is not a working code, just an example to show that if you use helper functions you can re-use your code in different parts of your application.

Qlic's avatar
Level 18

@SaeedPrez thank you for your help, i tried it using http://stackoverflow.com/a/32772686/2952393 as a guide. It's working for the images on the site itself, but unfortunally it's still not displaying the images inside the pdf.

Routes:

use App\Helpers\Helper;

Route::group(['middleware' => 'myMiddleware'], function() {

    Route::get('photo/{lead}/{type}/{name}',  ['as' => 'inventory.photo', function ($lead, $type, $name)  {

        return Helper::displayPhoto($lead, $type, $name);

    }]);

}]);

Helper:

<?php

namespace App\Helpers;

use Image;

class Helper
{
    public static function displayPhoto($lead, $type, $name)
    {
        switch($type) {
            case 1:
                $folder = 'roof';
                break;
            case 2:
                $folder = 'meterboard';
                break;
            case 3:
                $folder = 'access';
                break;
            case 4:
                $folder = 'converter';
                break;
            case 5:
                $folder = 'cable';
                break;
        }

        return Image::make(storage_path() . '/app/photo/'. $lead .'/'. $folder .'/'. $name)->response();
    }
}

Template:

<img src="{{ Helper::displayPhoto($foo, $bar, $bla) }}" alt="Test" />

Config\app.php:

'Helper'    => App\Helpers\Helper::class, // added to alisasses

composer.json:

"autoload-dev": {
        "classmap": [
            "tests/TestCase.php",
            "app/Libraries",
            "app/Helpers"
        ]
    },

Also did dump-autoload through ssh on the server.

Qlic's avatar
Level 18

After doing some further testing, here's what i found:

//1) From a regular template, calling the image route does return an image
{!! Html::image(route('inventory.photo', [$foo, $bar, $bla])) !!}  // shows image as expected

//2) From the same regular template, calling the image method does not return an image, or at least not as expected.
<img src="{{ Helper::displayPhoto($foo, $bar, $bla) }}" /> // src remains empty, however, when i place a return 'test'; inside the method, src does show test, so at least i know it's inside the method.

{{ dd(Helper::displayPhoto($foo, $bar, $bla)) }} // shows me image data
SaeedPrez's avatar

@Qlic I'm not really sure what error message you get (if any) or what the Image class is and why you need to use it. Can't you simply use something like..

$photo = '/app/photo/'. $lead .'/'. $folder .'/'. $name; 
return Storage::get($photo);
SaeedPrez's avatar

Also, have you checked what DOMPDF wants? I mean does it want the actual image or does it only want a path to the image?

Qlic's avatar
Level 18

@SaeedPrez i don't get any error messages, also i'm testing the method directly inside a regular template view to make sure wit works without a call to the route, so this is even before it's called in DOMPDF.

Also i tried the strorage get, same story, the img src remains empty, but when i diedump the call, it does contain data.

<?php

namespace App\Helpers;

use Image;
use Storage;

class Helper
{
    public static function displayPhoto($lead, $type, $name, $plain=null)
    {
        switch($type) {
            case 1:
                $folder = 'roof';
                break;
            case 2:
                $folder = 'meterboard';
                break;
            case 3:
                $folder = 'access';
                break;
            case 4:
                $folder = 'converter';
                break;
            case 5:
                $folder = 'cable';
                break;
        }

        if ($plain) {
            return Storage::get('photo/'. $lead .'/'. $folder .'/'. $name);
        }

        return Image::make(storage_path() . '/app/photo/'. $lead .'/'. $folder .'/'. $name)->response();
    }
}
DivDax's avatar

Had the same problem. Get your route out of the route group where you use a middleware with auth.

Qlic's avatar
Level 18

@DivDax well yes, that works, however than everyone can still access my images, which is exactly what i want to prevent.

SaeedPrez's avatar

@Qlic as I wrote in my last reply, I believe DOMPDF wants the path to the image, not the content of it.

<img src="/path/to/image.jpg" alt="Test" />
SaeedPrez's avatar

well yes, that works, however than everyone can still access my images, which is exactly what i want to prevent.

Are you trying to get the image through a route? I thought that was the first problem we tackled, that you shouldn't do that and instead use helpers..

Qlic's avatar
Level 18

@SaeedPrez i read that, but i'm currently not even testing it on DOMPDF, i wanted to see wether or not calling both the route and method worked, so i created a plain blade template, which i call through a controller, so without DOMPDF.

When both of those work, than i'll be able to shift my focus to getting it to work in DOMPDF aswell.

  • EDIT: It's working now, i altered my method to return base64 encoded data, and this works in both a regular template ánd in the DOMPDF template, so in the end, SaeedPrez you helped me alot by changing the image response to within a helper function.
<?php

namespace App\Helpers;

use Image;
use Storage;

class Helper
{
    public static function displayPhoto($lead, $type, $name, $plain=null)
    {
        switch($type) {
            case 1:
                $folder = 'roof';
                break;
            case 2:
                $folder = 'meterboard';
                break;
            case 3:
                $folder = 'access';
                break;
            case 4:
                $folder = 'converter';
                break;
            case 5:
                $folder = 'cable';
                break;
        }

        if ($plain) {
            return Image::make(storage_path() . '/app/photo/'. $lead .'/'. $folder .'/'. $name)->encode('data-url');
        }

        return Image::make(storage_path() . '/app/photo/'. $lead .'/'. $folder .'/'. $name)->response();
    }
}

Now i only have to add a fourht parameter to the images i want back as base64 encoded, and it works like a charm.

SaeedPrez's avatar

@Qlic Alright, glad it works.

The lesson here is to never put code in routes or in controllers, because it's not their responsibility and the code will not be reusable in other parts of your application.

Edit: @Qlic I meant alright, not already ☺

1 like

Please or to participate in this conversation.