rhand's avatar
Level 6

Flysystem 3 media load path post Laravel 9 upgrade

I created a Laravel Shift pull request to upgrade our application to Laravel 9. Been working on making all packages play nice. Fork of CTF0's Laravel Media Manager https://github.com/ivenms/laravel-media-manager works with Laravel 9. So added it. But our own internal copy of app/Http/Controllers/Editor/MediaController.php with some customizations then needed some updates.

I am stuck replacing old way to load storage path per project working with new Flysystem 3 setup. This is current or old Media controller:

<?php

namespace App\Http\Controllers\Editor;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use App\Models\Editor\Project;
use ivenms\MediaManager\App\Controllers\Modules\Delete;
use ivenms\MediaManager\App\Controllers\Modules\Download;
use ivenms\MediaManager\App\Controllers\Modules\GetContent;
use ivenms\MediaManager\App\Controllers\Modules\GlobalSearch;
use ivenms\MediaManager\App\Controllers\Modules\Lock;
use ivenms\MediaManager\App\Controllers\Modules\Move;
use ivenms\MediaManager\App\Controllers\Modules\NewFolder;
use ivenms\MediaManager\App\Controllers\Modules\Rename;
use ivenms\MediaManager\App\Controllers\Modules\Upload;
use ivenms\MediaManager\App\Controllers\Modules\Utils;
use ivenms\MediaManager\App\Controllers\Modules\Visibility;
use ivenms\MediaManager\App\Events\MediaFileOpsNotifications;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Image;
use League\Flysystem\Plugin\ListWith;

class MediaController extends Controller
{
    use Utils,
        GetContent,
        Delete,
        Download,
        Lock,
        Move,
        Rename,
        Upload,
        NewFolder,
        Visibility,
        GlobalSearch;

    ...

    public function __construct()
    {
        $this->currentProject = Project::getProjectFromSession();
        if (! $this->currentProject) {
            return response()->json([
                'success' => false,
            ], 500);
        }

        $config = app('config')->get('mediaManager');

        $this->fileSystem = $config['storage_disk'];
        $this->ignoreFiles = $config['ignore_files'];
        $this->fileChars = $config['allowed_fileNames_chars'];
        $this->folderChars = $config['allowed_folderNames_chars'];
        $this->sanitizedText = $config['sanitized_text'];
        $this->unallowedMimes = $config['unallowed_mimes'];
        $this->LMF = $config['last_modified_format'];
        $this->GFI = $config['get_folder_info'] ?? true;
        $this->paginationAmount = 9999;

       $this->storageDisk = app('filesystem')->disk($this->fileSystem);
        $this->storageDisk->getAdapter()->setPathPrefix(public_path('/uploads/'.$this->currentProject->id));
        $this->storageDiskInfo = app('config')->get("filesystems.disks.{$this->fileSystem}");
        $this->baseUrl = url('/uploads/'.$this->currentProject->id);
        $this->db = app('db')
                                    ->connection($config['database_connection'])
                                    ->table($config['table_locked']);

        $this->storageDisk->addPlugin(new ListWith());
...

The new Media Controller file has

$this->storageDisk     = Storage::disk($this->fileSystem);
$this->storageDiskInfo = app('config')->get("filesystems.disks.{$this->fileSystem}");
$this->baseUrl         = $this->storageDisk->url('/');
$this->db              = app('db')
                             ->connection($config['database_connection'])
                             ->table($config['table_locked']);

and I can use part of that and get rid of old addPlugin and ListWith parts. But how can I make

$this->storageDisk = app('filesystem')->disk($this->fileSystem);
 $this->storageDisk->getAdapter()->setPathPrefix(public_path('/uploads/'.$this->currentProject->id));

load media from the project directory? I can no longer use getAdapter() nor setPathPrefix. Tried a few things with path() but need an object for follow up variables.

How can I make this work and load media from project the new Flysystem way?

0 likes
2 replies
rhand's avatar
Level 6

When I used

...
$this->storageDisk     = Storage::disk($this->fileSystem)->path(public_path('/uploads/'.$this->currentProject->id));
$this->storageDiskInfo = app('config')->get("filesystems.disks.{$this->fileSystem}");
$this->baseUrl = url('/uploads/'.$this->currentProject->id);
$this->db = app('db')
                ->connection($config['database_connection'])
                ->table($config['table_locked']);
}
...

I get string issues

@var string $storageDisk
Expected type 'object'. Found 'string'.intelephense(1006)

and using

$directory = public_path('/uploads/'.$this->currentProject->id);
$this->storageDisk     = Storage::disk($this->fileSystem)->allFiles($directory);

it is an array and again not an object..

rhand's avatar
rhand
OP
Best Answer
Level 6

Thanks to our senior developer we managed to load files and work with Flysystem 3 in the end.

For the constructor of the Laravel Media Manager media controller we now use this

 public function __construct()
    {
        $this->currentProject = Project::getProjectFromSession();
        if (! $this->currentProject) {
            return response()->json([
                'success' => false,
            ], 500);
        }

        $config = app('config')->get('mediaManager');

        $this->fileSystem = $config['storage_disk'];
        $this->ignoreFiles = $config['ignore_files'];
        $this->fileChars = $config['allowed_fileNames_chars'];
        $this->folderChars = $config['allowed_folderNames_chars'];
        $this->sanitizedText = $config['sanitized_text'];
        $this->unallowedMimes = $config['unallowed_mimes'];
        $this->LMF = $config['last_modified_format'];
        $this->GFI = $config['get_folder_info'] ?? true;
        $this->paginationAmount = 9999;

        app()['config']->set('filesystems.disks.public_upload.root', public_path('/uploads/'.$this->currentProject->id));
        $this->storageDisk = Storage::build(app('config')->get('filesystems.disks.public_upload'));

        $this->storageDiskInfo = app('config')->get("filesystems.disks.{$this->fileSystem}");
        $this->baseUrl = url('/uploads/'.$this->currentProject->id);
        $this->db = app('db')->connection($config['database_connection'])
                                ->table($config['table_locked']);
    }

This part:

app()['config']->set('filesystems.disks.public_upload.root', public_path('/uploads/'.$this->currentProject->id));
$this->storageDisk = Storage::build(app('config')->get('filesystems.disks.public_upload'));

does the general loading now instead of using the older Flysystem plugin. It uses the app() helper - https://laravel.com/docs/master/helpers#method-app - as before with old code:

 $this->storageDisk = app('filesystem')->disk($this->fileSystem);
$this->storageDisk->getAdapter()->setPathPrefix(public_path('/uploads/'.$this->currentProject->id));

But we use app() to return a service container for dependency injection for [config] and set the disk root ( link ). Then we use that data to load that data for the storage disk of the media manager.

Please or to participate in this conversation.