I'm messed with the paths to get UniSharp / laravel-filemanager working on the server. In local mode it works perfectly but now I'm making the change of routes for production in online mode and I am not clear at all.
The problem is that it loads the images but they are not displayed either on the page or in the filemanager itself. In filemanager, I can see a red square with a cross (as error).
Let's see if anyone knows how to write the correct routes. I have tried many things but I'm messed.
The server files scaffolding:
server_files
my_laravel_app
public_html
another_files
The config filesystem.php file in Laravel:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('public_html'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
],
'links' => [
public_path('storage') => storage_path('app/public'),
],
I have, default uploading path in filemanager's lfm.php:
'disk' => 'public',
In case it helps something, this is my index.php ubicated at public_html:
if (file_exists(__DIR__.'/../my_app_laravel/storage/framework/maintenance.php')) {
require __DIR__.'/../my_app_laravel/storage/framework/maintenance.php';
}
require __DIR__.'/../my_app_laravel/vendor/autoload.php';
$app = require_once __DIR__.'/../my_app_laravel/bootstrap/app.php';
And this is ServiceProviders.php
public function register()
{
$this->app->bind('path.public', function() {
return base_path().'/public_html';
});
}
How should be the correct path in filesystem to allow filemanager can access to images and display them?
Note: the public_html folder has the symbolic link as you can see at filesystem.php.
I have checking routes and I solved temporary:
I changed:
'public' => [
'driver' => 'local',
/* this */ 'root' => storage_path('app/public'),
/* this */ 'url' => env('APP_URL').'/storage/app/public',
'visibility' => 'public',
],
And now I can upload and see the images in file manager and inside the web app. But now the problem is that users can visit the image url and see the private route of the folder:
http//mi_lar_app/storage/app/public/photos/31/art_1/fig_1.0.png
Some help????
If you have similar problems, the procedure I do in this case was to create a symbolic link with routes (I created a php file because I haven't access to SSH on my server):
<?php
/*__DIR__ is the directory file, where you save this file.php */
$mytargetDIR = __DIR__.'/../mi_lar_app/storage';
$mylinkDIR = __DIR__.'/storage';
symlink($mytargetDIR,$mylinkDIR);
echo 'Todo ok/ Symlink process successfully completed';
?>
And important, remember clean cache and routes every changes. If you don't have SSH access:
<?php
Artisan::call('cache:clear');
Artisan::call('config:cache');
Artisan::call('route:cache');
Artisan::call('view:clear');
return 'Todo limpio/All is cleaned';
?>
And next this little explanation, some help to me?? :)
Related
when I try to visualise my picture with this basic url on google :
domain.com/storage/transports/picture.png
I get (404) not found.
(I don't have this error for a file outside the storage symlink in my tree picture and I can totaly see it without any problems, exemple :
domain.com/logo.svg
I have used php artisan storage:link to create the symlink, so far I'm abble to store the pictures exactly where I want to with that controller :
public function storeTransports(Request $request)
{
try{
session(['content'=>'content_transports']);
$request->validate([
'name' => [ 'string', 'max:255'],
'picture' => [ 'required','image','mimes:jpeg,png,jpg,gif,svg', 'max:2048']
]);
if(Transport::where('name', $request->name)->first()){
return redirect(RouteServiceProvider::HOME)->with('error_transports', 'Transport already exists');
}
else{
if($request->hasFile('picture')){
$sanitized_image_name = strtolower(preg_replace("([^A-Za-z0-9])", "", $request->name)).'_'.time();
$image_name = $sanitized_image_name.'.'.$request->picture->extension();
Transport::create([
'name' => $request->name,
'path_picture' => $image_name
]);
$request->picture->storeAs('public/transports',$image_name);
}
}
return redirect(RouteServiceProvider::HOME)->with('success_transports', 'Transport saved successfully');
} catch (\Illuminate\Database\QueryException $e){
return redirect(RouteServiceProvider::HOME)->with('error_transports',$e->errorInfo);
}
}
I can also visualize my pictures in my public folder :
i've rm rf public/storage many times already
here is my configfiles.php :
<?php
return [
'default' => env('FILESYSTEM_DISK', 'public'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'throw' => false,
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'throw' => false,
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
],
'links' => [
public_path('storage') => storage_path('app/public'),
],
];
I appreciate your help, I've been looking at all the stackoverflow talking about that for the past hour.
PS: I don't use vagrant.
EDIT:
i finally fixed my issue, as Matty10209 mentoned here,
"[...]When running "php artisan storage:link", Laravel creates an absolute path for the image to your local directory. Docker does not like this and wants a relative one, so it breaks the image link and you get a 404. You have to create the symlink manually[...]"
"[...] Go to docker and the CLI of your project container (should be at the bottom). Delete the current symlink you have created with Laravel, then navigate to the path you wish to create a new one. and run
ln -s ../storage/app/public storage
[...]"
voyager project is installed on a subdomaine. https://sub.domainname.com/ ,
There is no problem in uploading images in local and I can show them But when i try it on hosting, the pictures appear broken, no matter what i did
APP URL
APP_URL=https://sub.domainname.com
Config/fileSystems
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
],
],
after uploading an image its image on the media menu
enter image description here
Did you publish the storage folder link? php artisan storage:link
Sorry, but is all your code inside the public_html folder? I mean, is there all including routes, storage, app, etc.?
This may affect the way your application considers where is the public folder. So you can open Tinker or add a log to see if the public_path() function is returning the correct path. If not, then you should instruct your application to redirect the path to the right folder or change the structure of your project to one more convenient/secure.
Also is the one from the example the subdomain? As it looks like a main domain.
PS: I don't know much about the cons, but most people doesn't recommend exposing paths here, like your project's domain or structure, as you don't know what can people do with that information.
Update Question
I'm uploading from my subdomain project to the storage folder in the root directory
this way I created a voyager storage in
'voyager' => [
'driver' => 'local',
'root' => '/home/username/public_html/storage/app/public',
'url' => 'https://website.com/storage',
'visibility' => 'public',
]
In my config/voyager.php file, I gave the disk I created custom.
'storage' => [
'disk' => 'voyager',
],
In this way, I can send images to the root directory of the project under public_html, but my images are still not visible on voyager.
The path of the images looks like this;
https://website.com/storage/works/July2022/5w9ONuhB1VgQFLj9hGJH.png
I'm trying to create a Dashboard for a personal project,
I want the storage of the Dashboard to be completely separate from the front end,
I create a new disk in the filesystem.php and this is the details:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'backend' => [
'driver' => 'local',
'root' => storage_path('app/backend'),
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
],
after that, I try to store some avatars and it works perfectly,
my problem is when I want to access the files from the view side,
Note that I try the visibility on both public and private
,also
I want to store sensitive files inside it
so I try:
url('/storage/avatars/filename.png'),
storage_path('backend/avatars/filename.png'),
storage::disk('backend')->get('avatars/filename.png'),
but nothing.
What is your question exactly? I assume you are trying to display images on a webpage, but they are not showing up?
This has to do with the visibility of your files. Only files in the storage/app/public directory are available for display. So images that should be visible using a URL, should be stored in that directory.
The best practice here is to upload the image to the Public disk. Make sure to create the symoblic link using php artisan storage:link.
For any other non-public file, you can set-up a Controller to return a download response
Another option is to display content right away in the browser, like a PDF. In that case, you should set the correct Content-Type while returning the response, with the contents of the PDF.
If this did not answer your question, please let me know.
On Laravel 8
file_get_contents(asset('storage/list.json');
Give me:
ErrorException
file_get_contents(http://localhost:8000/storage/list.json): failed to
open stream: HTTP request failed!
But: http://localhost:8000/storage/list.json exist and it is accesible via browser for example.
On my config/filesystem.php iv'e:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0600,
],
'dir' => [
'public' => 0775,
'private' => 0700,
],
],
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
And ive created the symbolic link with:
php artisan storage:link
command.
I've tried even to add manually file perssion to storage folder as described in the filesystem.php but nothing change.
You should use absolute paths when you want to work with files. file_get_contents() is fine. There are some file wrappers available in laravel but internally they all use file_get_contents().
Try
file_get_contents(public_path(asset('storage/list.json')));
If getting from storage file try
file_get_contents(storage_path('app/assets/list.json'));
See https://laravel.com/docs/5.5/helpers#method-resource-path
I'm trying to store a file in the public folder storage/app/public/ but for some reason Laravel just seems to put it in the private storage/app/ folder.
If I understand correctly I'm supposed to just set the visibility to 'public' but that doesn't seem to change anything:
Storage::put($fileName, file_get_contents($file), 'public');
When I call getVisibility I get public so that seems to work fine:
Storage::getVisibility($fileName); // public
These are the settings in my filesystems.php:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET'),
],
],
When you call Storage::put, Laravel will use the default disk which is 'local'.
The local disk stores files at its root: storage_path('app'). The visibility has nothing with where the file should be stored.
You need to choose the public disk which will store the files at its root: storage_path('app/public'),
To do that, you need to tell Laravel which disk to use when uploading the file. Basically change your code to this:
Storage::disk('public')->put($fileName, file_get_contents($file), 'public');