Laravel: show images which are outside of root directory - laravel

I need to display a series of images that are outside the root directory.
I've been reading about creating a symbolic link but I can't get my head around it at all.
In the filesystems.php file, the disk pointing to that directory is:
'communication' => [
driver' => 'local',
'root' => '/var/www/communication',
],
'links' => [
public_path('storage') => storage_path('app/public'),
],
What I think I should make is a symbolic link pointing from "/var/www/communication" to "app/public" but it's not clear to me at all.
Please, could someone help me or guide me with this issue?
Thanks in advance.

In your app/public you need to create a symbolic link to /var/www/communication
ln -s /var/www/communication communication
Your app/public/communication now points to /var/www/communication.
'communication' => [
'driver' => 'local',
'root' => public_path('communication'),
]

Related

How to retrieve file from Laravel storage subfolder?

I'm trying to retrieve a file from this path in a laravel project:
/storage/app/public/blog/3.jpg
These approaches produce following errors:
1.
$image = Storage::disk('public')->get('/storage/blog/3.jpg');
->
local.ERROR: File not found at path: storage/blog/3.jpg {"userId":16,"exception":"[object] (Illuminate\\Contracts\\Filesystem\\FileNotFoundException(code: 0): File not found at path: storage/blog/3.jpg at /Users/artur/PhpstormProjects/safa-ameedee.com/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php:171)
[stacktrace]
$image = Storage::disk('public')->get('/storage/app/public/blog/3.jpg');
$image = Storage::get('/storage/app/public/blog/3.jpg');
->
local.ERROR: File not found at path: storage/app/public/blog/3.jpg {"userId":16,"exception":"[object]
The weird thing is that I store the files in the storage like so:
Storage::disk('public')->put('/blog/' . $request->path, $image);
So should they not be retrievable in the same way?
TL/DR
Storage::disk('public')->get('block/3.jpg');
Explanation
The problem is you're putting storage in the path for some reason. It's not necessary and is leading to the wrong path being built.
Take a look at the default filesystems config:
'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,
],
The root is what is useful to see here. storage_path() returns the full path to the storage folder. So something like storage_path('folder_1') -> /home/user/project/storage/folder_1.
The local disk is the default, so just doing Storage::get() will use it automatically.
You're using the public disk, so the actual location of these files is storage/public (symlinked into public/storage). This means doing Storage::disk('public') already begins at /home/user/project/storage/app/public. Adding storage again makes the path incorrect.
Using path may help with future debugging. Storage::disk('public')->path('block/3.jpg') will output the full path, and you can see where it's going wrong. For your code given it would probably show something like /home/user/project/storage/app/public/storage/app/public.

Shared Hosting Laravel 8 Hosting problem: Symlink is not working

I need the deploy my laravel project to the web. With this introduction But the hosting provider is Doesn't allow me to use a symbolic link(symlink), I called customer service, and told me blocked for security reasons.
So, since I do not use symbolic links, there are big problems in uploading images and deploying them.
Is there a way to do deployment my app?
Change your disk configurations in the config/filesystems.php to read and write to public folder via public_path() function.
If you're deploying over a shared host, you probably have another folder like public_html as your public folder which is not included in your source. Try to link to the public_html using dots ../../public_html/
'public' => [
'driver' => 'local',
// 'root' => storage_path('app/public'),
'root' => public_path(),
'url' => env('APP_URL'),
'visibility' => 'public',
],
'photos' => [
'driver' => 'local',
'root' => public_path('photos'),
'url' => env('APP_URL') . '/photos',
'visibility' => 'public',
],
Another way is just create something like symlink using php, example you can create a route like below:
Route::get(
'/storage/{file}',
function ($file) {
$filepath = "../storage/app/public/".$file;
header("Cache-Control: public");
header("Content-Type: ".mime_content_type($filepath));
header('Content-Length: '.filesize($filepath));
readfile($filepath);
die();
}
);
Maybe not best practice, but it will solve your problem. It's will do same as symlink.

Laravel store files with permissions 774

Im loosing mind. I upload files via laravel API, they are stored in folder and file always get permission 644, is there any way how to store files as 775 ?
can i somehow add this to my function ?
(0755, true, true)
function for store files:
$result=$request->file('file_path')->store('apiFiles/'.$idParameter);
thanks for any help
In laravel you can use 'public' or 'private' disks and set the permissions options in the config file filesystems.php
https://laravel.com/docs/8.x/filesystem#permissions
The public visibility translates to 0755 for directories and 0644 for files. You can modify the permissions mappings in your filesystems configuration file:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0600,
],
'dir' => [
'public' => 0775,
'private' => 0700,
],
],
],
You can then store files with specific visibility like it suggests here https://laravel.com/docs/8.x/filesystem#file-visibility
Or you can use the built in php function chmod()
https://www.php.net/manual/en/function.chmod.php
you can change permission of file after creating them by chmod command like this:
$result=$request->file('file_path')->store('apiFiles/'.$idParameter);
chmod('file path',0775);

Illuminate\Contracts\Filesystem\FileNotFoundException in Laravel 5.6 using Storage facade

This code is returning an strange error:
$file = Storage::get(Storage::disk('notas_xml')->path('') . 't.txt');
As you can see the file does exist.
Get the file directly from the disk
$exists = Storage::disk('notas_xml')->exists('t.txt');
if ($exists) {
$file = Storage::disk('notas_xml')->get('t.txt');
}
And if you didn't setup notas_xml disk in filesystems.php
$file = Storage::get('public/arquivos/notas_xml/t.txt');
And to use your code, you need to setup a disk like so in config/filesystems.php
'notas_xml' => [
'driver' => 'local',
'root' => storage_path('app/public/arquivos/notas_xml'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
And get the file simply like this
$file = Storage::disk('notas_xml')->get('t.txt');
You need to get the file as below code:
Storage::disk('notas_xml')->has('t.txt');
Above has method may be used to determine if a given file exists on the disk:
Please read documentation https://laravel.com/docs/5.1/filesystem#retrieving-files
To better understand all this... The trick is in: config/filesystems.php
If you have this code (which is the default value of Laravel in Github)
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
This Facade Storage will act in the folders
root_laravel_project/storage/app
So if you want to check if an "israel.txt" file exists
if( Storage::exists('israel.txt') ){
echo "File found. And it exists on the path: root_laravel_project/storage/app/israel.txt";
}
Remember that up to this point it has nothing to do with the symbolic link php artisan storage: link
This symbolic link is only to make a folder called "public" within the "storage" folder be part of the public access through HTTP
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
Then at the time of doing the sym. You can access the files by http (which are public for any user)
This example assumes that you are using a virtual host (and if not, you must do it as a recommendation for work better locally)
http:// root_laravel_project.test/storage/israel-alvarez.txt
Or so that it is better understood as in the old school without a virtual host
http:// localhost/public/storage/israel-alvarez.txt
Then these urls will look inside your folder
root_laravel_project/storage/app/public/israel-alvarez.txt
Laravel's documentation is somewhat brief and can be confusing regarding this issue. But you just have to remember that one thing is to access through the "storage Facade" (which is the correct way to upload and verify if there are files) and another thing is to access through the http (through url) which is the symbolic link (which is the treatment you already give to users to download files or see if it is a PDF for example).
I hope it helps. Good day

Storing files outside the Laravel 5 Root Folder

I am developing a laravel 5 project and storing image files using imagine. I would want to store my image files in a folder outside the project's root folder. I am stuck at the moment The external folder where image files are supposed to be stored, I want to make it accessible via a sub-domain something like http://cdn.example.com Looking towards your solutions.
The laravel documentation could give you a helping hand.
Otherwise you could go to config/filesystems.php and add your own custom storage path for both local and production:
return [
'default' => 'custom',
'cloud' => 's3',
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path().'/app',
],
'custom' => [
'driver' => 'custom',
'root' => '../path/to/your/new/storage/folder',
],
's3' => [
'driver' => 's3',
'key' => 'your-key',
'secret' => 'your-secret',
'region' => 'your-region',
'bucket' => 'your-bucket',
],
'rackspace' => [
'driver' => 'rackspace',
'username' => 'your-username',
'key' => 'your-key',
'container' => 'your-container',
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
'region' => 'IAD',
],
],
];
get ur path name from base_path(); function, then from the string add your desired folder location.
suppose ur
base_path() = '/home/user/user-folder/your-laravel-project-folder/'
So ur desired path should be like this
$path = '/home/user/user-folder/your-target-folder/'.$imageName;
make sure u have the writing and reading permission
You can move all or a part of storage folder in any folder of yours in your server. You must put a link from old to new folder.
ln -s new_fodler_path older_folder_path
You can make a new virtual host to serve the new folder path.

Resources