Cant write to public folder in laravel - php

I'm trying to manage my fileuploading but it seems I cant write to the folder public/uploads.
I have write permission so I'm not sure what it can be, does somebody see a typo?
I use the intervention/image library.
My code is:
$file = Input::file($fileName);
if ($file->isValid()) {
if ($file->getMimeType() == 'image/jpeg' || $file->getMimeType() == 'image/png') {
$path = public_path("uploads", $file->getClientOriginalName());
Image::make($file->getRealPath())->resize(180, null)->save($path);
} else {
throw new FileException;
}
}
The exception thrown is:
Intervention \ Image \ Exception \ NotWritableException
Can't write image data to path (/home/vagrant/Sites/cms/public/uploads)

I've found the typo...
I had:
$path = public_path("uploads", $file->getClientOriginalName());
Changed to:
$path = public_path("uploads/" . $file->getClientOriginalName());
Thanks for the quick answer though!

You need to check the permissions of the folder, and its parent folders. If you're on linux, it should be 644. The individual folder may have write access, but the parent might not; or it could be for the wrong user. Check the Ownership group too.

Related

laravel - Using unllink to delete file, receive is a directory error

Helo.
I have a question. Just now, when I tried to delete a picture using only unlink without the # symbol, it returned the "unlink is a directory" error. What is the reason that causes it? I received an advice that using the symbol # to the unlink is a bad practice, but somehow this is the method that works.
$file = $request->file('image');
if($file->getSize() < 2048000){
$path = storage_path('app/public/' . $event->img);
if (file_exists($path)) {
unlink($path);
}
$filename = Str::uuid() . "." . $file->getClientOriginalExtension();
$event->img = $request->image->storeAs('events', $filename, 'public');
}
// Create and save post with validated data
$event->save();
In the for loop, it is possible that one of the image names is empty and unlink is trying to delete a directory instead of file. unlink is only used to delete files and not directories. If you try to delete a directory using unlink, you will get an error. See the documentation for unlink.
The file_exists function checks whether a file or directory exists. Since you want to check if file exists and not directory, then you should use the is_file function instead of file_exists. See the documentation for is_file.

Copying folder to other folder with PHP

I'm trying to move folder to other folder, with all it's files. Both folders are in root directory. Tried a lot of ways, and always get no result.
Here is my latest atempt:
$source = "template/"
$dest = "projects/"
function copyr($source, $dest){
if (is_link($source)) {
return symlink(readlink($source), $dest);
}
if (is_file($source)) {
return copy($source, $dest);
}
if (!is_dir($dest)) {
mkdir($dest);
}
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
copyr("$source/$entry", "$dest/$entry");
}
$dir->close();
return true;
}
Need professional glance to tell me, where I'm getting it wrong?
EDIT:
Sorry for wrong tags.
Problem is - nothing is happening. Nothing is being copied. No error messages. Simply nothing happens.
File structure:
I suggest to try and do the following
How do you run the scrips? Do you open page in browser or run script in command line? If you open page in browser this might be an issue with permissions, paths (relative and not absolute) and errors not shown but logged.
Use absolute folder paths instead of relative paths. For example /var/www/project/template.
Apply realpath() function to all paths and check (output) the result. If path is wrong (folder does not exist, separators are wrong etc) you will get empty result from the function.
Make sure to use DIRECTORY_SEPARATOR instead of / if you run your script on Windows. I can not check if / works on Windows now but potentially this might be an issue. For example
copyr($source.DIRECTORY_SEPARATOR.$entry", $dest.DIRECTORY_SEPARATOR.$entry);
Check warnings and errors. If you do not have permission you should get warning like this
PHP Warning: mkdir(): Permission denied
You may need to enable warnings and errors if they are disabled. Try for example to make an obvious mistake with name and check if you get any error message.
Try to use tested solution from one of the answers. For example xcopy function.
Try to add debug messages or run your script in debugger step by step. Check what is happening, what is executed etc. You can add debug output near any operator like (just an idea):
echo 'Creating directory '.$name.' ... ';
mkdir($name);
echo (is_dir($name) ? 'created' : 'failed').PHP_EOL;

Cannot save image intervention image. NotWritableException in Image.php line 138

Im trying to save a manipulated image which i will them push to s3.
My code that works This code saves the image directly within the public folder*
public function store(Filesystem $filesystem)
{
$request = Input::all();
$validator = Validator::make($request, [
'images' => 'image'
]);
if ($validator->fails()) {
return response()->json(['upload' => 'false']);
}
$postId = $request['id'];
$files = $request['file'];
$media = [];
$watermark = Image::make(public_path('img/watermark.png'));
foreach($files as $file) {
$image = Image::make($file->getRealPath());
$image->crop(730, 547);
$image->insert($watermark, 'center');
$image->save($file->getClientOriginalName());
}
}
What i would like to achieve is to be able to save it within a folder of it's own. Firstly what is the best place to store an image for a blog post, within the storage of public folder? But anyway when i do this:
$image->save('blogpost/' . $postId . '/' . $file->getClientOriginalName());
// Or this
$image->save(storage_path('app/blogpost/' . $postId . '/' . $file->getClientOriginalName()));
I get the error:
folder within public
NotWritableException in Image.php line 138: Can't write image data to
path (blogpost/146/cars/image.jpg)
or
storage path
NotWritableException in Image.php line 138: Can't write image data to
path /code/websites/blog/storage/app/blogpost/146/image.jpg
I've tried
cd storage/app/
chmod -R 755 blogpost
And it still wont work
Thank you for reading this
Ok so here is how i solved it, I made the directory first before storing,
Storage::disk('local')->makeDirectory('blogpost/' . $postId);
Once the folder is created i then go on to store the manipulated images like so:
$image->save(storage_path('app/blogpost/' . $postId . '/' . $imageName));
And then pushing the image to S3
$filesystem->put('blogpost/' . $postId . '/' . $imageName, file_get_contents(storage_path('app/blogpost/' . $postId . '/' . $imageName)));
This worked
You can solve it by casting the Intervation/Image variable to a data stream using function stream. Then use the Storage Laravel facade to save the image.
$img = Image::make('path-to-the-image.png')->crop(...)->insert->stream('jpg', 90)
Storage::put('where_I_want_the_image_to_be_stored.jpg', $img);
Laravel 5 needs permission to write to entire Storage folder so try following,
sudo chmod 755 -R storage
if 755 dont work try 777.
Am improving #Amol Bansode answer.
You are getting this error because $postId folder does not exist in the path you specified.
You could do it like this:
//I suggest you store blog images in public folder
//I assume you have created this folder `public\blogpost`
$path = public_path("blogpost/{$postId}");
//Lets create path for post_id if it doesn't exist yet e.g `public\blogpost\23`
if(!File::exists($path)) File::makeDirectory($path, 775);
//Lets save the image
$image->save($path . '/' . $file->getClientOriginalName());
In my case I migrated a project from Windows 10 to Parrot (Debian-Linux) and I had the same problem and turned out the slashes were backward slashes and Linux interpret them differently. Unlike Windows, it doesn't really matter.
//Windows Code:
$image_resize->save(public_path('\storage\Features/' .'Name'.".".'png'));
//Linux Code (Working):
$image_resize->save(public_path('storage/Features/' .'Name'.".".'jpg'));
I know the question is related to Laravel but I came across from making it to work with WordPress. If somebody is coming from WordPress world, this code works (I was getting the same 'cannot write' error) and changing directory permission would not work as the library probably needs the relative path (the code below is valid for direct installation of Intervention through composer into any PHP application, not Laravel per se)-
require 'vendor/autoload.php';
use Intervention\Image\ImageManager;
$manager = new ImageManager(array('driver' => 'imagick'));
$image = $manager->make('PUBLIC IMAGE URL/LOCAL IMAGE PATH');
$image->crop(20, 20, 40, 40);
$image->save(__DIR__ . '/img/bar.png');
in my case:
i double check my symlinks in filesystem.php in config folder in laravel
and remove all symlink then regenerate them
php artisan storage:link
in my case my fileName is not valid format for naming in windows but it worked on linux or docker
$make_name = date('Y-m-d-H:i:s') . hexdec(uniqid()) . '.' . $img->getClientOriginalExtension();
when I remove this date('Y-m-d-H:i:s') it worked as well
I have faced the same issue but 775 permission not sort it so I changed the write permission to the folder(also sub-folders) to 777 to get over this issue.

Laravel file upload NotFoundHttpException

I'm using Laravel to upload an image to my folder.
$file = Input::file('largeImage');
$filePath = '/uploads/'.date("Y/m").'/'.time().'/';
$path = $filePath;
$file->move($path, $file->getClientOriginalName());
The image is successfully uploaded.
Now when I try to access it:
http://localhost:8080/uploads/2015/01/1420644761/10377625_673554946025652_6686347512849117388_n.jpg
I'm having the Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException error.
I even tried http://localhost:8080/public/uploads/2015/01/1420644761/10377625_673554946025652_6686347512849117388_n.jpg
But the same error. What might be the problem? I checked the uploads folder and the image is there.
You need to add a call to public_path helper:
$filePath = public_path() . '/uploads/'.date("Y/m").'/'.time().'/';
Otherwise it will place it in the app root, I think.
This worked for me:
$file = Input::file('largeImage');
$filePath = '/uploads/'.date("Y/m").'/'.time().'/';
$filename = $file->getClientOriginalName();
$path = public_path().$filePath;
$file->move($path, $file->getClientOriginalName());
Ok, so it IS a Routing Issue. To solve this particular one, define a Route::get that navigates to your file.
Route::get("/download/{year}/{month}/{time}/{filename}", "Controller#downloadFile");
Then you'll need a function in that controller that handles the file download:
public function downloadFile($year, $month, $time, $filename){
$path = public_path()."/uploads/".$year."/".$month."/".$time."/".$filename".jpg";
// Should equate to: "/uploads/2015/01/142064476110377625_673554946025652_6686347512849117388_n.jpg
return Response::download($path, 'image.jpg');
}
Which in theory should work for your needs. The path may need to be modified to fit your needs but this should be the general idea. Test that out and let me know if it works.
Note
This isn't the best way to handle downloads, as you need to know the exact filename of the file you want, but it points you in the right direction.

Unable to delete file after uploaded. (move_uploaded_file)

Greetings anyone who is reading this!
Currently I have a php page that allows the user to upload a file to my server at a specified directory. Here is what I use to do that:
if(isset($_FILES['fileup']) && strlen($_FILES['fileup']['name']) > 1) {
chmod($uploadpath, 0777);
$uploadpath = $uploadpath . basename( $_FILES['fileup']['name']); // gets the file name
$sepext = explode('.', strtolower($_FILES['fileup']['name']));
$type = end($sepext); // gets extension
list($width, $height) = getimagesize($_FILES['fileup']['tmp_name']); // gets image width and height
$err = ''; // to store the errors
// If no errors, upload the image, else, output the errors
if($err == '') {
if(move_uploaded_file($_FILES['fileup']['tmp_name'], $uploadpath)) {
chmod($uploadpath, 0777);
echo '<br/><br/>File successfully uploaded:' .$uploadpath.'</b>';
}
else echo '<b>Unable to upload the file.</b>';
}
else echo $err;
}
The uploading part works like a charm and the file is uploaded fine to the server however once uploaded, I am unable to delete the file as another user. Currently the user uploading the file would be the Apache user "www-data".
I do believe that the issue has to do with permissions being set for the uploaded file which I have tried using:
chmod($uploadpath,0777);
This does not help though.. The file still can't be removed. I can remove it through SSH if I am root using "rm -rf /directorypath" but can't delete it if I browse to it.
Any suggestions? Any help is greatly appreciated!
if you want to remove a file you can use php unlink ! And if thats a directory then rmdir !
you could use unlink('upload_folder/'.$image['file_name']);
Try to allow permission to your image folder too not just the files underneath.
chmod($upload_path, 0777);
before the line
$uploadpath = $uploadpath . basename( $_FILES['fileup']['name']);
Note that 777 is not super safe anyway. Best practice is to manage users with the group www-data

Categories