I am trying to upload multiple images at once. The files are being uploaded but they pass the validation even if they are not a valid iamge. I want to upload all valid files and return a message with the ammount of files that werent uploaded succesful.
My function:
public function addImages($id, Request$request)
{
$files = Input::file('images');
$uploaded = 0;
$failed = 0;
foreach ($files as $file) {
// Validate each file
$rules = array('file' => 'required|image');
$validator = Validator::make(array('file'=> $file), $rules);
if($validator->passes()) {
$destinationPath = 'uploads';
$filename = $file->getClientOriginalName();
$upload_success = $file->move($destinationPath, $filename);
if($upload_success){
$uploaded ++;
}
else {
$failed ++;
}
} else {
$failed ++;
}
}
\Session::flash('success_message',$uploaded.' files uploaded.');
if($failed > 0){
\Session::flash('errors','Some files werent valid.');
}
return redirect('admin/myroute/'.$id);
}
For some reason if I upload files withhout any extension they are still uploaded. What am I doing wrong?
You should not validate it in controller, You should use each method for it, example in Your Request file.
protected function getValidatorInstance()
{
$validator = parent::getValidatorInstance();
$validator->each('files', ['image']);
return $validator;
}
This simply checks all the files.
more information,
Laravel API about validation
if your taking about validation you should specify like file types you can specify the the name and make a validation like this 'image' => 'mimes:jpeg,jpg,bmp,png' . Hope this would help
Related
I am new in Laravel and I develop a web application where someone can upload a car ad and other users can write comments bellow that. Instead of developing a simple CRUD application I thought about developing also a table that will be related to these ads and will store the photos. Up to this point, I have made the relations, I can show images and I have two problems: The first problem is that not all images are moved to storage/photos folder and the second problem is that all the records in the database have the same name. For example, if I want to upload images 1,2,3 then in the database all the files will have the name 1.
Bellow, you may find the store code. This code stores all the ads and also the images if they exist.
public function store(Request $request)
{
//
$this->validate($request, [
'name' => 'required',
'cc' => 'required',
'desc' => 'required',
'date' => 'required'
]);
$ad = new Ad;
$ad->name = $request->input('name');
$ad->cc = $request->input('cc');
$ad->desc = $request->input('desc');
$ad->date = $request->input('date');
$ad->user_id = auth()->user()->id;
$ad->save();
if ($request->hasFile('photos')) {
$allowedfileExtension = ['pdf', 'jpg', 'png', 'docx'];
$files = $request->file('photos');
foreach ($files as $file) {
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
//$file->move('storage/photos', $filename);
$check = in_array($extension, $allowedfileExtension);
if ($check) {
foreach ($request->photos as $photo) {
$photo->move('storage/photos', $filename);
$img = new AdsPhoto;
$img->ad_id = $ad->id;
$img->filename = $filename;
$img->save();
}
return redirect('/home')->with('success', 'ad + image created');
} else {
echo '<div class="alert alert-warning"><strong>Warning!</strong> Sorry Only Upload png , jpg , doc</div>';
}
}
}
return redirect('/home')->with('success','ad created');
}
Thank you in advance!
1st mistake, you did looping twice
2nd mistake (you might not realize this) you didnt merge the filename and extension, this will cause an issue when you retrieving the image in blade
therefore correction on your code plus comment to explain it
if ($request->hasFile('photos')) {
$allowedfileExtension = ['pdf', 'jpg', 'png', 'docx'];
$files = $request->file('photos');
foreach ($files as $file) {
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
//$file->move('storage/photos', $filename);
$check = in_array($extension, $allowedfileExtension);
$fullpath = $filename . '.' . $extension ; // adding full path
if ($check) {
// removing 2nd loop
$file->move('storage/photos', $fullpath); // you should include extension here for retrieving in blade later
$img = new AdsPhoto;
$img->ad_id = $ad->id;
$img->filename = $filename;
$img->save();
}
} else {
echo '<div class="alert alert-warning"><strong>Warning!</strong> Sorry Only Upload png , jpg , doc</div>';
}
}
return redirect('/home')->with('success', 'ad + image created');
}
From the documentation, if you want to put your file on storage instead of on public folder you need to put these few lines of code as below in the your controller class
<?php
...
use Illuminate\Support\Facades\Storage;
...
class YourController extends Controller{
...
// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));
...
}
This command will put your file into storage folder
I am trying to upload an image from my react native project using laravel as my backend framework.
This is the data I send :
I receive a warning that my network request failed.
Here is my backend code :
public function upload(Request $request)
{
$image = $request->get('data');
$name = 'Sup';
Image::make($request->get('data'))->save(public_path('images/').$name);
$fileupload = new Fileupload();
$fileupload->filename=$name;
$fileupload->save();
return response()->json(['message' => 'Success']);
}
I have a function, you can try it!
Please change the path before doing anything else (this is the code used to upload one - multiple files at once)
public function uploadImage (Request $request) {
$files = $request->file('images');
$fileText = '';
foreach($files as $file) {
$rules = array('file' => 'required|mimes:png,gif,jpeg');
$validator = Validator::make(array('file' => $file), $rules);
if($validator->passes()){
$destinationPath = 'storage/images/';
$filename = $file->getClientOriginalName();
$unique_name = md5($filename. time()).$filename;
$upload_success = $file->move($destinationPath, $unique_name);
$fileText .= url('storage/images/' . $unique_name) . '|';
}
}
return rtrim($fileText, '|');
}
$destinationPath = public_path().'/uploads/';
if (Input::hasFile('photo'))
{
$res = Input::file('photo')->move($destinationPath);
echo $destinationPath;
if($res)
{
echo '<br />good';
}
else
{
echo 'bad'.$res;
}
exit;
}
my enctype form is enctype="multipart/form-data", the uploads folder exists and its access is 777, the above statement returns good, the path is correct, what I'am doing wrong?
$photo = Input::file('photo');
if (Input::hasFile('photo'))
{
$file = Input::file('photo');
$destinationPath = public_path().'/uploads/';
$filename = $file->getClientOriginalName();
$uploadSuccess = $file->move($destinationPath, $filename);
$user->logo_path = $filename;
}
$object->save();
// Don't forget to save it using a save function, otherwise your hard work will be for nothing
// $object : use your object like user, car, ...
I'm trying to upload images into a Laravel app that will then need to be publicly displayed. However, I seem to only be able to upload to a folder within the application root. Any attempt to upload to the public directory throws the following error:
protected function getTargetFile($directory, $name = null)
{
if (!is_dir($directory)) {
if (false === #mkdir($directory, 0777, true)) {
throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
I'm assuming this means that Laravel is going to prevent me from uploading to any file that is publicly accessible. I actually rather like this, however, how can I link to images that are outside of the public directory I've tried to ../ my way out of the public folder, but appropriately, that didn't work.
Alternately, anything that will let me uploaded directly to the public folder would be great too.
If it helps, here is my controller method that puts the file in public folder:
$thumbnail_file = Input::file('thumbnail');
$destinationPath = '/uploads/'. str_random(8);
$thumbnail_filename = $thumbnail_file->getClientOriginalName();
$uploadSuccess = Input::file('thumbnail_url')->move($destinationPath, $thumbnail_filename);
Route::post('upload', function(){
$avarta = Input::file('avatar');
if(strpos($avarta->getClientMimeType(),'image') !== FALSE){
$upload_folder = '/assets/uploads/';
$file_name = str_random(). '.' . $avarta->getClientOriginalExtension();
$avarta->move(public_path() . $upload_folder, $file_name);
echo URL::asset($upload_folder . $file_name); // get upload file url
return Response::make('Success', 200);
}else{
return Response::make('Avatar must be image', 400); // bad request
}});
will upload to /public/assets/uploads folder, maybe help you
Your destination path should be:
$destinationPath = public_path(sprintf("\\uploads\\%s\\", str_random(8)));
Try using this one in your controller after creating a folder called uploads in your public and another folder called photos in uploads.
$data = Input::all();
$rules = array(
'photo' => 'between:1,5000|upload:image/gif,image/jpg,image/png,image/jpeg',
);
$messages = array(
'upload' => 'The :attribute must be one of the following types .jpg .gif .png .jpeg',
'between' => 'The :attribute file size must be 1kb - 5mb'
);
$validator = Validator::make($data, $rules, $messages);
if($validator->passes())
{
$uploads = public_path() . '/uploads/photos';
$photo = Input::file('photo');
$photodestinationPath = $uploads;
$photoname = null;
if($photo != null)
{
$photoname = $photo->getClientOriginalName();
Input::file('photo')->move($photodestinationPath, $photoname);
}
$thumbnail = new Model_name();
$thumbnail ->column_name_in_table = $photoname;
and then put this in your routes
Validator::extend('upload', function($attribute,$value, $parameters){
$count = 0;
for($i = 0; $i < count($parameters); $i++)
{
if($value->getMimeType() == $parameters[$i])
{
$count++;
}
}
if($count !=0)
{
return true;
}
return false;});
In the ImageProductController.php (Controller) file insert the following code:
public function store(Request $request, $id)
{
if ($request->hasFile('image')){
$rules = [
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg'
];
$this->validate($request, $rules);
// Save file in directory
$file = $request->file('image');
$path = public_path() . '/images';
$fileName = md5(rand(0,9999)).'.'.$file->getClientOriginalExtension();
$file->move($path, $fileName);
$imageProduct = new ImageProduct();
$imageProduct->image = $fileName;
}
In the file create.blade.php (View) insert the following code:
<form enctype="multipart/form-data" method="post" action=" " >
{{ csrf_field() }}
<label for="image" class="btn btn-primary">Inserir Imagem</label>
<input type="file" name="image" id="image" accept="image/*"
class="form-control" value="{{ old('image') }}>
</form>
In the ImageProduct.php file (Model) insert the following code:
public function getUrlAttribute()
{
if(substr($this->image, 0, 4) === "http"){
return $this->image;
}
return '/images/'.$this->image;
}
Good luck!
You need to give permission the laravel folder where you want to store images.
The commend is:
sudo chown www-data:www-data /var/www/html/project-name/path/to/folder.
Any best way to do this will be gratefull
what this do is grab the input from a form and save it to the database.
public function update()
{
$file = Input::file('path');
$destinationPath = 'img/';
$filename = $file->getClientOriginalName();
// $extension =$file->getClientOriginalExtension();
$upload_success = Input::file('path')->move($destinationPath, $filename);
$photo = Photo::find($_POST['id']);
$photo->caption = $_POST['caption'];
$photo->path = $destinationPath . $filename;
$photo->save();
if( $upload_success ) {
return Redirect::to('photos/'.$_POST['id'].'/edit')->withInput()->with('success', 'Photo have been updated.');
} else {
return Response::json('error', 400);
}
}
this work just fine but i wonder if there a simplify way to do this like how i can get post data from the form send to update to update the photo information instead of me using the $_POST and get the id from the form parse into the update($id) ect. Thanks
You can use the Input class, instead of accessing the post directly.
I would probably re-write the function a little like this:
public function update()
{
$file = Input::file('path');
$destinationPath = 'img/';
$filename = $file->getClientOriginalName();
if( Input::file('path')->move($destinationPath, $filename) )
{
$photo = Photo::find(Input::get('id'));
$photo->caption = Input::get('caption');
$photo->path = $destinationPath . $filename;
$photo->save();
return Redirect::to('photos/'.$_POST['id'].'/edit')->withInput()->with('success', 'Photo have been updated.');
}
else
{
return Response::json('error', 400);
}
}
The other option is to extract some of this data directly into your Photo model, and do it in there.