Can't write image data to path in laravel - laravel-4

I am having the same error as this guy is :
Another thread
basically the error i have is uploading the image to the specific path, my code is as follows :
public function postCreate() {
$validator = Validator::make(Input::all() , Product::$rules);
if ($validator->passes()) {
$product = new Product;
$product->category_id = Input::get('category_id');
$product->title = Input::get('title');
$product->description = Input::get('description');
$product->price = Input::get('price');
$image = Input::file('image');
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
$product->image = 'public/img/products'.$filename;
$product->save();
return Redirect::to('admin/products/index')
->with('message' , 'Product created');
}
return Redirect::to('admin/products/index')->with('message' , 'something went wrong')
->withErrors($validator)->withInput();
}
I was just trying to follow a tutorial on laravel e-commerce web application.
I guess the problem is that i don't have write permisson in my directory , how do i add write permission in my directory. I.E. the public folder, I googled a few places , but i don't understand what is it that i have to edit ?
I.E the htaccesss file or can i make write changes on the cmd ? also how do i check what weather a directory is write protected .
PS. i am using windows . i am attaching a screenshot of the error .
Thank you.

You might want to change the dateformat since windows doesn't allow colons in filenames:
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
And you also might want to add a trailing slash to your path so it doesn't concatenate the filename to the folder path:
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);

Generally this error occurs when you do not yet have the directory that will store the image inside the public directory. Sometimes it can be a permission issue.
Does you img directory exists in your public directory?
To fix this, follow the steps:
Use this snippet:
$relPath = 'img/'; //your path inside public directory
if (!file_exists(public_path($relPath))) { //Verify if the directory exists
mkdir(public_path($relPath), 666, true); //create it if do not exists
}
Or manually create the img directory in public
2.Then you can save your image:
Image::make($image)->resize(468, 249)->save(public_path('img/products'.$filename)); //save you image
$product->image = 'img/products'.$filename; //note
$product->save();
**NOTE: We do not need to specify the public directory in the path because we are using a relative path. The img directory will be created inside public directory.

Along with this, you need to make sure the folder path exists and which has right permissions set.
$relPath = 'img/product/';
if (!file_exists(public_path($relPath))) {
mkdir(public_path($relPath), 777, true);
}
Where $relPath is the path relative to public directory.
This requirement is however windows specific. In linux, folder directory will be created if it does not exist.

I also recommend all of you to check if $path exists. Like Jose Seie use native PHP check, I recommend you to thought about build-in helpers.
This can be achieved with File Facade helper:
File::exists($imagePath) or File::makeDirectory($imagePath, 777, true);
Advice you to use Laravel built-in functions, classes & helpers to improve the performance of your application!

well , i made the correction that john suggested and then made the following corrections :
I replaced the below code :
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
with :
$path = public_path('img/products/'.$filename);
Image::make($image->getRealPath())->resize(468, 249)->save($path);
problem solved , i don't know why public_path works , but never mind .

Related

Safety in laravel file upload

I have a simple question.. Is it safe to have a app that has a file upload system for users to send images to our project, and store those files in this directory?
$file->move(public_path('../storage/app/public/files'), $name);
Or is it better to store in:
$file->move(public_path('files'), $name);
This way it stores the file in the "files" directory inside the public directory.
That would be ok and also depends on your app and number of users but I recommend to change the name of the file and also you can accept only JPG or PNG file for more security for changing the name of the file you can do it like this :
$image_name = rand() . '.' . $image->getClientOriginalExtension();
$image->move(public_path('images'), $image_name);
with this function you can get all data from db for that id then you can show whatever you want in the blade
public function show($id)
{
$data = YOUR_MODEL::findOrFail($id);
return view('view', compact('data'));
}

How to delete photo from project's public folder before updating data in lumen/laravel?

I am trying to delete photo from my projects public folder before updating another photo. My code looks like-
if(File::exist( $employee->avatar)){
//$employee->avatar looks /uploads/avatars/1646546082.jpg and it exist in folder
File::delete($employee->avatar);
}
This is not working in my case. If I comment these code then another photo updated without deleting perfectly. How can I solve the issue!
try php unlink function
$path = public_path()."/pictures/".$from_database->image_name;
unlink($path);
This is the code which i use in update profile picture you can do this exactly like this
$data=Auth::user();
if($request->hasFile('image')){
$image = $request->file('image');
$filename = 'merchant_'.time().'.'.$image->extension();
$location = 'asset/profile/' . $filename;
Image::make($image)->save($location);
$path = './asset/profile/';
File::delete($path.$data->image);
$in['image'] = $filename;
$data->fill($in)->save();
}

Laravel Image File path not working on server

I have my laravel application hosted on a server in the root directory as follow:
./Project
I have my images folder inside public folder of the project which reside in public_html with the path as following:
./public_html/project/images
How can i upload image on this path from my controller and also how to retrieve data from there?
what i have tried so far for uploading is:
https://www.mywebsite.com/project/images
but it didn't worked for me. can i have a little help on how to resolve this issue
For inserting data, you can use:
$request->file('image')->store('your-path');
Example:
$name = $request->file('image')->getClientOriginalName();
$path = $request->file('image')->store('public/store/images');
$save = new Photo;
$save->name = $name;
$save->path = $path;
$save->save();
And for retrieving an image:
$getImage = {{asset('images/your-image-name')}}

Laravel 5.4 - File Storage returns false when checking for file existence

I am trying to see if a file exist in the storage folder. It returns false in the server even if the file exist. In my local environment, it is working perfect.
I am trying to store avatar for users. When I check if avatar exists, it returns false.
Store avatar:
$avatar = $request->file('avatar');
$user = Auth::user();
if($avatar && $file = $avatar->isValid()) {
$file = $request->file('avatar');
$path = $user->avatar_path;
$image = Image::make($file)->fit(100,100)->encode('jpg');
Storage::put($path, $image);
$url = Storage::url($path);
}
Checking for avatar existence
$user = Auth::user();
if ($user->has_avatar) {
Storage::delete($user->avatar_path);
}
has avatar method in user.php model
public function getHasAvatarAttribute()
{
return Storage::disk('public')->has('avatars/'.md5($this->id . $this->email).'.jpg');
}
Avatar path function
public function getAvatarPathAttribute()
{
return 'public/avatars/'. md5($this->id . $this->email) . '.jpg';
}
When I test on my machine, all is good. On server, it returns false even if avatar exists.
I can not comment Yet so I will leave this answer here. In production it is not working? As in a live server? Maybe linux server? And you are running the local development on Windows? See where I am going with this? Your path maybe wrong. I mean the naming. Even a to A or vice versa may effect the path. The same goes for your file naming. And path naming. avatar/something and /avatar/something are completely different.
Please let me know if that was the case.

Laravel : To rename an uploaded file automatically

I am allowing users to upload any kind of file on my page, but there might be a clash in names of files. So, I want to rename the file automatically, so that anytime any file gets uploaded, in the database and in the folder after upload, the name of the file gets changed also when other user downloads the same file, renamed file will get downloaded.
I tried:
if (Input::hasFile('file')){
echo "Uploaded</br>";
$file = Input::file('file');
$file ->move('uploads');
$fileName = Input::get('rename_to');
}
But, the name gets changed to something like:
php5DEB.php
phpCFEC.php
What can I do to maintain the file in the same type and format and just change its name?
I also want to know how can I show the recently uploaded file on the page and make other users download it??
For unique file Name saving
In 5.3 (best for me because use md5_file hashname in Illuminate\Http\UploadedFile):
public function saveFile(Request $request) {
$file = $request->file('your_input_name')->store('your_path','your_disk');
}
In 5.4 (use not unique Str::random(40) hashname in Illuminate\Http\UploadedFile). I Use this code to ensure unique name:
public function saveFile(Request $request) {
$md5Name = md5_file($request->file('your_input_name')->getRealPath());
$guessExtension = $request->file('your_input_name')->guessExtension();
$file = $request->file('your_input_name')->storeAs('your_path', $md5Name.'.'.$guessExtension ,'your_disk');
}
Use this one
$file->move($destinationPath, $fileName);
You can use php core function rename(oldname,newName) http://php.net/manual/en/function.rename.php
Find this tutorial helpful.
file uploads 101
Everything you need to know about file upload is there.
-- Edit --
I modified my answer as below after valuable input from #cpburnz and #Moinuddin Quadri. Thanks guys.
First your storage driver should look like this in /your-app/config/filesystems.php
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'), // hence /your-app/storage/app/public
'visibility' => 'public',
],
You can use other file drivers like s3 but for my example I'm working on local driver.
In your Controller you do the following.
$file = request()->file('file'); // Get the file from request
$yourModel->create([
'file' => $file->store('my_files', 'public'),
]);
Your file get uploaded to /your-app/storage/app/public/my_files/ and you can access the uploaded file like
asset('storage/'.$yourModel->image)
Make sure you do
php artisan storage:link
to generate a simlink in your /your-app/public/ that points to /your-app/storage/app/public so you could access your files publicly. More info on filesystem - the public disk.
By this approach you could persists the same file name as that is uploaded. And the great thing is Laravel generates an unique name for the file so there could be no duplicates.
To answer the second part of your question that is to show recently uploaded files, as you persist a reference for the file in the database, you could access them by your database record and make it ->orderBy('id', 'DESC');. You could use whatever your logic is and order by descending order.
You can rename your uploaded file as you want . you can use either move or storeAs method with appropiate param.
$destinationPath = 'uploads';
$file = $request->file('product_image');
foreach($file as $singleFile){
$original_name = strtolower(trim($singleFile->getClientOriginalName()));
$file_name = time().rand(100,999).$original_name;
// use one of following
// $singleFile->move($destinationPath,$file_name); public folder
// $singleFile->storeAs('product',$file_name); storage folder
$fileArray[] = $file_name;
}
print_r($fileArray);
correct usage.
$fileName = Input::get('rename_to');
Input::file('photo')->move($destinationPath, $fileName);
at the top after namespace
use Storage;
Just do something like this ....
// read files
$excel = $request->file('file');
// rename file
$excelName = time().$excel->getClientOriginalName();
// rename to anything
$excelName = substr($excelName, strpos($excelName, '.c'));
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;
$excel->move(public_path('equities'),$excelName);
This guy collect the extension only:
$excelName = substr($excelName, strpos($excelName, '.c'));
This guy rename its:
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;

Resources