barryvdh / laravel-elfinder

elFinder bundle for Laravel
739 stars 171 forks source link

config set root and dir in my controller not working #230

Open jihadismail8 opened 6 years ago

jihadismail8 commented 6 years ago

hi , i am trying to change the root dir for elfinder , i made this controller

public function finder($name,$projectid,$DU_id)
{
    $path = public_path().'/files/1/projects/'.$name.'-'.$projectid.'/'.$DU_id;
        if (!File::exists( $path)) {
            File::makeDirectory($path, 0755, true,true);
        }
        \Config::set('elfinder.roots','files/1/projects/'.$name.'-'.$projectid.'/'.$DU_id);
       return redirect(route('elfinder.index'));
}

but after the redirection to elfinder , the root is not set as i want it to be set , its just gives me the publick root dir , i tried to dump config get of elfinder.root in this contoller and it shows that it is correctly set , and when i dump it inside the showConnector function in ElfinderController.php it just shows null ?? whats the problem ? anybody can help please

jihadismail8 commented 6 years ago

anyone ???

biwerr commented 6 years ago

Your setting will be lost after redirection. Elfinder loads the config from elfinder.php on every request. To change the settings for one special case you have to implement your own controler to pass your custom config.

Have a look at default controller implementation https://github.com/barryvdh/laravel-elfinder/blob/master/src/ElfinderController.php#L74-L125

yelnyafacee commented 6 years ago

Does this means I should create a new controller with a modified 'showConnector()'

and also change all the routes?

where is the route file located?

biwerr commented 6 years ago

Does this means I should create a new controller with a modified 'showConnector()'

Yes, i my option it is the only way to load your custom config with the variables passed by the request.

and also change all the routes?

It depends, if you overwrite the default Routes wich are registered in the ServiceProvider , the URL will be the same, but would be handled in your controller

Example:

config/elfinder.php

....
'route' => [
        'prefix' => 'elfinder',
        'middleware' => 'permission:module.core.files', //Set to null to disable middleware filter
    ],
....

app/Http/routes.php

....
Route::group($this->app['config']->get('elfinder.route', []);, function () {
            Route::get('/',  ['as' => 'elfinder.index', 'uses' =>'YourCustomController@showIndex']);
            Route::any('connector', ['as' => 'elfinder.connector', 'uses' => 'YourCustomController@showConnector']);
            Route::get('popup/{input_id}', ['as' => 'elfinder.popup', 'uses' => 'YourCustomController@showPopup']);
            Route::get('filepicker/{input_id}', ['as' => 'elfinder.filepicker', 'uses' => 'YourCustomController@showFilePicker']);
            Route::get('tinymce', ['as' => 'elfinder.tinymce', 'uses' => 'YourCustomController@showTinyMCE']);
            Route::get('tinymce4', ['as' => 'elfinder.tinymce4', 'uses' => 'YourCustomController@showTinyMCE4']);
            Route::get('ckeditor', ['as' => 'elfinder.ckeditor', 'uses' => 'YourCustomController@showCKeditor4']);
});
....

Code not testet

yelnyafacee commented 6 years ago

I cloned the 'ElfinderController' class and created my own routes files,

I changed the showConnector() function code to:


    public function showConnector()
    {
        $roots = $this->app->config->get('elfinder.roots', []);
        if (empty($roots)) {

            //$dirs = (array) $this->app['config']->get('elfinder.dir', []);
            $dirs = (array) config('elfinder.dir');

            foreach ($dirs as $dir) {
                $roots[] = [
                    'driver' => 'LocalFileSystem', // driver for accessing file system (REQUIRED)
                    'path' => public_path($dir), // path to files (REQUIRED)
                    'URL' => url($dir), // URL to files (REQUIRED)
                    'accessControl' => $this->app->config->get('elfinder.access') // filter callback (OPTIONAL)
                ];
            }

            $disks = (array) $this->app['config']->get('elfinder.disks', []);
            foreach ($disks as $key => $root) {
                if (is_string($root)) {
                    $key = $root;
                    $root = [];
                }
                $disk = app('filesystem')->disk($key);
                if ($disk instanceof FilesystemAdapter) {
                    $defaults = [
                        'driver' => 'Flysystem',
                        'filesystem' => $disk->getDriver(),
                        'alias' => $key,
                    ];
                    $roots[] = array_merge($defaults, $root);
                }
            }
        }

        if (app()->bound('session.store')) {
            $sessionStore = app('session.store');
            $session = new LaravelSession($sessionStore);
        } else {
            $session = null;
        }

        $rootOptions = $this->app->config->get('elfinder.root_options', array());
        foreach ($roots as $key => $root) {
            $roots[$key] = array_merge($rootOptions, $root);
        }

        $opts = $this->app->config->get('elfinder.options', array());
        $opts = array_merge($opts, ['roots' => $roots, 'session' => $session]);

        // run elFinder
        $connector = new Connector(new \elFinder($opts));
        $connector->run();
        return $connector->getResponse();
    }

but the config still wont persist, any idea how to keep it?

biwerr commented 6 years ago

Where is your changed config? I see you only loading your default app config from config/elfinder.php

        $roots = $this->app->config->get('elfinder.roots', []);

...
       $dirs = (array) config('elfinder.dir');
...

Where are the variables from you initial post ($name,$projectid,$DU_id)?

For you info: $this->app['config']->get('elfinder.dir', []); does the same as config('elfinder.dir');

Your showConnector() is exact the same, you have changed nothing. The only line you changed is this

//$dirs = (array) $this->app['config']->get('elfinder.dir', []);
                $dirs = (array) config('elfinder.dir');

So could you explain where you load the custom config from in showConnector() function?

jihadismail8 commented 6 years ago

i used redis cache to store the dir , user press's on link or button or whatsever , and in route i made a function to sit a redis value , then i redirect it to elfinder route .then in the elfindercontroller request for the value of dir from redis , and sit it as the dir , then i delete it from redis

yelnyafacee commented 6 years ago

@jihadismail8 hi, which redis driver are you using?

jihadismail8 commented 6 years ago

Use any ,doesn't matter !

yelnyafacee commented 6 years ago

@jihadismail8 If I change the structure of the dir everytime I access elfinder popup from different routes ( like edit shop page, edit User profile page etc ), what happens if 2x person that login with same account, one is uploading images to the popup from edit shop page while another is uploading image at edit user profile page, what will happen to the dir stored in redis? will it get corrupted? or assign the wrong dir structure?

biwerr commented 6 years ago

@yelnyaface if you store the informationen with current session id, this should not be a problem. Or you have to generate a token for upload

jihadismail8 commented 6 years ago

@biwerr , session wont work . @yelnyaface well its almost impossible that two persons will request the same route at exact same second ! so when first user request the route to elfinder , the redis value is set , then a second later the user 2 requests the same route , that redis value will be updated .