Search code examples
laravellaravel-5.7laravel-excel

Laravel / Laravel-Excel missing forward slash in asset url


I am uploading excels in Laravel for processing with Laravel-Excel. I have the following issue:

When I do this:

$file = $request->file('file')->store('Questionnaires', ['disk' => 'public']);

$file = asset($file);

dd($file);

I get something as expected, like:

http://project.test/Questionnaires/filename.xlsx

However, when I pass $file that into Laravel-Excel thus:

$collection = Excel::toCollection(new QuestionnairesImport, $file);

I get this error:

File not found at path: http:/project.test/Questionnaires/filename.xlsx

This is missing a forward slash in the http:/ ie http://

What's going on?


Solution

  • OK, I solved this and am saving the answer here for my oown record and in case it is useful to someone else.

    Disclaimer: I still don't know with who the error lay, so consider this a work around/ bug fix/ terrible idea - as you like.

    I modified two core files in this way:

    In the function readStream() in vendor/league/flysystem/src/adapter/local.php:

        // original lines, removed:
        //$location = $this->applyPathPrefix($path);
        //$stream = fopen($location, 'rb');
    
        // my addition (1 line):
        $stream = fopen(asset($path), 'rb');
    

    In the function readStream() in vendor/league/flysystem/src/filesystem.php:

        // original line, removed:       
        //$this->assertPresent($path);
    
        // my addition (1 line):
        $path = str_replace('http:/a','http://a', $path);
    

    In the first function it was failing because it couldn't open the path - a local prefix was being added in front of the web address.

    In the second function, it couldn't assert the file as present because one of the forward slashes had been removed (still not quite sure how...). So I just did a string replace to put it back in ('a' is the first letter of my project name in APP_URL in .ENV - you need to change it to the first letter of your project for this to work.

    This feels a horribly dirty way to do it, but it works. Hopefully I'll come across a better solution.