Does Laravel have a convention for a local permanent uploaded file storage location? - laravel

I have some forms that allow the user to upload files that only they can view so I will have to store them somewhere. However, I haven't been able to find any information about where these files would usually be stored if I want them to be kept on the local server. Therefore I have to assume that there is no convention for the permanent storage location of uploaded files. Am I correct in this assumption?
To be clear, I'm not talking about temporary storage locations.
Additionally, would it be a bad idea to have the storage location of all the files as a subfolder of the app directory (with gitignore enabled on it)? Or would it be a better idea to have it outside of the app folder? Thanks!

There is no explicit convention on where to store user uploaded files.
However Laravel ships with a storage directory where it stores framework related data such as cache, sessions, etc. As the name denotes it's a good place to store files, not just framework files. Also the Laravel Filesystem Documentation mentions that the default configured location is storage/app (but that can be changed to fit your needs):
When using the local driver, note that all file operations are relative to the root directory defined in your configuration file. By default, this value is set to the storage/app directory. Therefore, the following method would store a file in storage/app/file.txt: Storage::disk('local')->put('file.txt', 'Contents');
This storage/app folder will by default be ignored by Git.
If you also need the files to be publicly available, then you have two options:
1. Store them somewhere in the public directory.
2. Store them in the storage directory as suggested above and create a symbolic link to the folder from a public location. On Linux you can run this:
ln -s /path/to/laravel/public/files /path/to/laravel/storage/app/files
Of course the directory names can be whatever you like, I used files as an example.
The first option is for cases where you don't have shell access or are otherwise unable to create symbolic links. So if possible I suggest you use the second option.

Laravel uploads to the temporary file path, then you will have to move the file:
$request->file('photo')->move($destinationPath);
This method will move the file from its temporary upload location (as determined by your PHP configuration) to a more permanent destination of your choosing.
SOURCE: https://laravel.com/docs/master/requests#files

Related

Symbolic link from public/storage to storage/app/public still makes the files in the storage directory accessible from the web

What I have done
When I researched about storing files in laravel. I came across two approaches.
Storing the assets directly inside the public folder.
Creating a symbolic link from public/storage to
storage/app/public
When I researched about which one two use, I came across this stack overflow link. 👉 Difference between storing files in public directory and in storage in Laravel 5.4
In this link in the top answer it was mentioned,
Public folder means files will be publicly accessible.
For example an image stored in
public/images/my-image.jpegcan be viewed by anyone by
going to mysite.com/images/my-image.jpeg
However, files stored in storage directory are only available to your
app.
👆 Since, including in the mentioned stack overflow post above, and many other posts I have read on different platforms implied the fact that files in the public directory are web accessible whereas the files inside the storage directory are not, I tried to test this by storing files both in the public directory and in the storage directory one at a time, and then checking if the files are accessible through the web url.
My attempts went as below,
First I added the path images/ in the public
directory and placed some images (Let us say
test1.jpg, test2.jpg and
test3.jpg) into that directory. Then inside my blade
template for the src attribute of my
img tags I referred to them as
URL('images/test1.jpg') etc... and they were indeed
rendered on the webpage. Then I also tried to access the images from
the url by going to
http://localhost:8000/images/test.jpg. The result was
as expected, The images were rendered on the web page + they were
accessible from the url
Then I ran the command php artisan storage:link
on the console, which according to the articles I read, should
create a symbolic link between the directories
public/storage and storage/app/public.
As soon as I ran the command, I got a new folder called
storage created in the public
directory. Then I moved all my images to that
public/storage directory. Then set the
src attribute my img tags as
URL('storage/test1.img') etc... the images were
rendered on the web page. Then I tried to check if the images are
still accessible from the url. for that on the url bar I went to
http://localhost:8000/storage/test1.jpg. The
images were STILL ACCESSIBLE from the url.
Problem
However, according to the answer I have mentioned and some other similar links, I expected those images to not be accessible from the url in the 2) above since the images should now be actually in the storage/app/public which we have created a symbolic link to from public/storage. (Files inside the storage directory should not be publicly accessible right?)
This led me to two questions,
Why are the images are still being accessible from the url even after I created a symbolic link from public/storage to storage/app/public and stored the images in the public/storage directory?
As happened with my case, if the files in the
public/storage are still accessible through the web
url, what are the advantages of actually creating the symbolic link?
It does not seem to offer any more security since the files are
still accessible from the url.
It would be really helpful if anyone can help me understand the answers to the above two questions I have. Thanks.
What's happening to you is the expected behavior.
The purpose of Laravel storage is to interact with your local files and make use of Laravel helpers, besides being easily shared across deployments.
Saying that I would avoid moving your files directly to your public folder.
On the other hand, by adding files to your storage/app/public folder you are assuming that those files will be publicly accessible, but they won't be until you create a symbolic link which is a special kind of file that points to another file.
When you create a symbolic link you are saying "hey, if the user reaches http://localhost:8000/storage/ just show the files stored in storage/app/public"
So if you want private files (and you have created a symbolic link) just don't upload them to your storage/app/public folder, instead of that put your private files out from the public folder such as storage/app/myfiles
He are your answers:
1 - Why are the images are still being accessible from the url even
after I created a symbolic link from public/storage to
storage/app/public and stored the images in the public/storage
directory?
Because in fact, you have created a symbolic link for that purpose, making the storage/app/public publicly accessible.
2 - As happened with my case, if the files in the public/storage are
still accessible through the web url, what are the advantages of
actually creating the symbolic link? It does not seem to offer any
more security since the files are still accessible from the url.
As said, the advantage is to make use of Laravel filesystem. The public link doesn't determine the privacy of your files
You might have many different types of files in one project. Some are accessible to the public, like images embedded in a website (as your example shows), and some are private files, let's say, for example, a pdf of a private report.
Any file that is accessible to the public can be stored in either storage/public or directly in public. As you have observed, no difference there since the former would have a symlink established.
However, private files cannot be stored storage/public (if symlink is established) and especially not directly in public folder for obvious reasons.
Those files can go in storage/app/NOT_PUBLIC_REPO. These files should be made accessible via protected routes (along with signed routes if you want extra protection).

Is there a proper path for storing images (Theme and Uploads) in Laravel?

I'm relatively new to Laravel - building a basic website with it - and I'm unclear as to where I'm suppose to store images.
My instinct said /resources/images but that path doesn't exist like /js and /css do.
I read that /storage/app/public/images could be, but the answers I'm finding are inconclusive.
I understand the local may differ if they were uploaded through a GUI by an end-user vs by a developer who is creating a theme / template.
I'd like a citation to official documentation assuming one exists. Thank you!
I unintentionally discovered this Laravel official documentation which explains the purpose of each directory. In that it states the following:
This (/public) directory also houses your assets such as images, JavaScript, and CSS.
Based on the next quote it's implied the above is referring to images uploaded by the developer for the front end. Whereas the following explicitely states it's for user-generated files:
The /storage/app/public directory may be used to store user-generated files, such as profile avatars, that should be publicly accessible.
Earlier in the documentation is makes a subtle but, presumably, essential note:
By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public.
#techcyclist rightly referenced more official documentation about how to reference these in their respective locations. Such as files in the /storage this way, and the public directory this way. It also mentions advanced options for storage such as Amazon S3 under "Specifying a Disk".
Usually images are stored in public folder and you can easily access then with /img/somepic.jpg from anywhere in your project. Also you can store them in storage/images but then you need to use function for relative path to storage.
image does not exist in resources folder it exists in public folder
try like this, it will pick public folder default.
{{url('images/image_name')}}

Best place to create a cache folder in a Laravel 5.1 environment for third party libraries to write

I am facing the following issue in the production server (not in local or dev):
production.ERROR: phpFastCache\Exceptions\phpFastCacheDriverException: PLEASE CREATE OR CHMOD /var/www/curator5/vendor/raiym/instagram-php-scraper/src/InstagramScraper/sessions/curatorlive.com/Files - 0777 OR ANY WRITABLE PERMISSION! in /var/www/curator5/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/PathSeekerTrait.php:110
On the following discussion: https://github.com/PHPSocialNetwork/phpfastcache/issues/441, they suggest to create a folder with absolute path for that library to write to. I was thinking to create a folder in storage/app called cache for that purpose, I know that in storage/framework/cache there is a similar folder for the framework to cache, I am not sure if I should use this folder instead.
My questions:
Where in the Laravel 5.1 directory structure is the best place to
create this folder?
Should I use the storage/framework/cache or
create a new one if so what is the best place to create it?
Reference to the folder cache I would like to create inside storage/app and the stuff the library will create inside that folder, in the following image:
Image

Laravel - where to store files which I don't want to share with users

For example, I want to merge two .png files in one .png file, but I don't want to share those parts with user. Currently I am storing files in storage folder, but the problem is that storage folder is with .gitignore file as default. Of course I could allow to push it to git, but I suppose it's not a good idea, because there could be thousands of another files uploaded by the user. Now if I want to continue work from another computer I should move all my parts manually.
So what you could advice to me?
You can store it anywhere you want in your application.
For example, you can make a folder in your projects root called /uploads and then use one of laravel helper functions to specify where to save the file:
Example:
$save_path = base_path('uploads');
You can use the Laravel File Class to make sure the path exists with:
File::makeDirectory($save_path, $mode = 0755, true, true);
You will need to add use File; in the top of the file with all the class includes.
Later, to access said files you can make a View Composer which you can add logic to in order to limit who can view the file.
If you want to protect your files so that nobody can access without permission store all file into storage folder. Don't put your file in public folder.

Where should we store data (files) from users in Laravel architecture?

I have a project that is meant to work for some countries. For now, in this example lets says USA-(us) and France-(fr).
So, when the user write in the URL us_mySite.com, the system should open the files, or display some pictures related to us only, not fr
At some point the user will need to update some file (pdf, excel, pictures, videos, etc) and the system must store these files inside the correct country.
So now we have in the site root a structure like this:
www/myStie/
...
...
data/
us/
excel/
pdf/
fr/ ...
img/
us/
fr/
...
...
Now I am migrating the system to Laravel 5 and I would like to know where should I put this data folder. Should it be inside Public/ folder? This folder should be accessible for delete, read, changes and save files trough the process.
This is quote from laravel doc: https://laravel.com/docs/master/structure#the-public-directory
The storage/app/public directory may be used to store user-generated
files, such as profile avatars, that should be publicly accessible.
You should create a symbolic link at public/storage which points to
this directory. You may create the link using the php artisan
storage:link command.
Store them in public folder.
https://laravel.com/docs/master/structure#the-public-directory.
That's where all the assets go. Check the above link for more info.

Resources