Can't upload photo in Laravel 4 - php

I'm trying to add some products to my database and I have to upload photo of this product. I've made a controller and view but when I click Create I don't have any errors but I don't have photo too. I want to upload only jpg,jpeg,gif,png files how can I do it? Here is my code:
Controller:
public function postAddProduct(){
$destinationPath = '';
$filename = '';
$newId = Product::max('id')+1;
$validator = Validator::make(Input::all(), array(
'name' => 'required',
'description' => 'required',
'partner_link' => 'required',
'image' => 'required'
));
if (Input::hasFile('image')) {
$file = Input::file('image');
$destinationPath = public_path().'/uploads/products/';
$filename = $newId.'.'.$file->getClientOriginalExtension();
$uploadSuccess = $file->move($destinationPath, $filename);
}
if($validator->passes()){
$product = new Product;
$product->name = Input::get('name');
$product->description = Input::get('description');
$product->category_id = Input::get('category');
$product->partner_link = Input::get('partner_link');
$product->photo = $filename;
$product->save();
return Redirect::back();
}else{
return Redirect::back()->withErrors($validator)->withInput();
}
}
View:
{{ Form::open(array('url'=>'user/admin/products/addd', 'class'=>'col-md-4', 'style'=> 'float:none; margin: 0 auto', 'id'=>'register-form')) }}
<h2 class="form-signin-heading">Add Product</h2>
{{ Form::text('name', null, array('class'=>'form-control', 'placeholder'=>'Name')) }}
{{ Form::text('description', null, array('class'=>'form-control', 'placeholder'=>'Description')) }}
{{ Form::text('partner_link', null, array('class'=>'form-control', 'placeholder'=>'Partner link')) }}
{{Form::label('category', 'Category: ', array('class' => 'field-name'))}}
<select name="category">
<?php $i = 0; ?>
#foreach($categories as $category)
<optgroup label="{{$category['name']}}">
#foreach($category['subcategories'] as $sub)
<option value="{{$sub->id}}">{{$sub->name}}</option>
#endforeach
</optgroup>
#endforeach
</select>
<div class="clearfix"></div>
{{Form::file('image', array('style' => 'margin-bottom: 10px'))}}
{{ Form::submit('Save', array('class'=>'btn btn-large btn-primary btn-block'))}}
{{ Form::close() }}

You form should have option 'files' set to 'true':
{{ Form::open(array('url' => 'foo/bar', 'files' => true)) }}

Related

Laravel can't pass value to controller after submitting to database

After submitting to the database and redirecting/reloading the page I get the error Trying to get property 'stockcount1' of non-object. I know it has to do with the product id not being properly passed back but I'm having trouble finding a fix.
show.blade.php
{!! Form::open(['action' => ['App\Http\Controllers\PagesController#addreview', $data['product']->id], 'method' => 'POST']) !!}
{{-- {{ Form::hidden('_method', 'PUT') }} --}}
<div class="form-group">
{{ Form::textarea('description', '', ['class' => 'form-control', 'placeholder' => 'Write your message']) }}
</div>
<div class="form-group">
{{ Form::label('rating', 'Rating') }}
{{ Form::select('rating', ['1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5'], '1') }}
</div>
{{ Form::submit('Submit', ['class' => 'btn btn-primary']) }}
{!! Form::close() !!}
web.php
Route::get('/addreview/{id}', 'App\Http\Controllers\ProductsController#show');
Route::post('/addreview/{id}', 'App\Http\Controllers\PagesController#addreview');
Route::get('/products/{id}', 'App\Http\Controllers\ProductsController#show');
pagescontroller.php
public function addreview(Request $request, $id)
{
$this->validate($request, [
'description' => 'required',
'rating' => 'nullable',
]);
$review = new Review;
$review->rating = $request->input('rating');
$review->reviewerid = auth()->user()->id;
$review->productid = $id;
$review->description = $request->input('description');
$review->save();
$product = Product::find($id);
$reviews = DB::table('reviews')->where('productid', '=', $id)->paginate(10);
$sum = $product->stockcount1 + $product->stockcount2 + $product->stockcount3;
$data = array();
$data['product'] = $product;
$data['stocktotal'] = $sum;
$data['reviews'] = $reviews;
$data['id'] = $id;
return redirect('/products/{$id}')->with('success', 'Review submitted')->with(compact('data'));
//return view('products.show')->with('success', 'Review submitted')->with(compact("data"));
}
productscontroller.php
$product = Product::find($id);
Log::info(print_r($id, true));
$reviews = DB::table('reviews')->where('productid', '=', $id)->paginate(10);
$sum = $product->stockcount1 + $product->stockcount2 + $product->stockcount3;
$data = array();
$data['product'] = $product;
$data['stocktotal'] = $sum;
$data['reviews'] = $reviews;
$data['id'] = $id;
return view('products.show')->with(compact('data'));
Had to change redirect('/products/{$id}') to redirect('/products/'.$id).
Thanks to #user3532758

Laravel can't save photo

I have function code below but it won't save photo not in database nor in file path.
Code
public function store(Request $request)
{
$this->validate($request, array(
'name' => 'required',
'price' => 'required|numeric',
'type_id' => 'required|numeric',
'photo' => 'required',
));
$item = new Menu;
$item->name = $request->input('name');
$item->price = $request->input('price');
$item->type_id = $request->input('type_id');
if ($request->hasFile('photo')) {
$photo = $request->file('photo');
$filename = 'MenuItem' . '-' . time() . '.' . $photo->getClientOriginalExtension();
$location = public_path('images/'. $filename);
Image::make($photo)->resize(500, 500)->save($location);
$item->photo = $filename;
}
$item->save();
Session::flash('success', 'Menu Item Saved Successfully.');
return redirect()->back();
}
dd($request->all()); of code above
array:5 [▼
"_token" => "awAvc7F8lOv9vKkfwyiTFj7jnQGszv8xjLQxcwRH"
"name" => "test"
"price" => "100"
"photo" => "air putih.jpg"
"type_id" => "1"
]
Any idea?
Update
Based on the Nabil Farhan answer below I was forgot about enctype="multipart/form-data" but now I'm getting
Intervention \ Image \ Exception \ NotReadableException
Unable to find file ().
Still not able to save my photo.
Update 2
I dd my requests again, now after adding enctype="multipart/form-data" it becomes strange:
array:5 [▼
"_token" => "awAvc7F8lOv9vKkfwyiTFj7jnQGszv8xjLQxcwRH"
"name" => "kerupuk"
"price" => "2000"
"type_id" => "3"
"photo" => UploadedFile {#805 ▼
-test: false
-originalName: "kerupuk.jpg"
-mimeType: "image/jpeg"
-error: 0
#hashName: null
path: "C:\Windows\Temp"
filename: "phpB195.tmp"
basename: "phpB195.tmp"
pathname: "C:\Windows\Temp\phpB195.tmp"
extension: "tmp"
realPath: false
aTime: 2019-02-12 04:57:39
mTime: 2019-02-12 04:57:39
cTime: 2019-02-12 04:57:39
inode: 0
size: 43933
perms: 0100666
owner: 0
group: 0
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
linkTarget: "C:\Windows\Temp\phpB195.tmp"
}
]
Why my photo field becomes like that?!
anyway here is my form in blade:
{{ Form::open(array('route' => 'menus.store', 'files' => true)) }}
<div class="row">
<div class="col-md-12">
<h5>Name</h5>
{{ Form::text('name', null, array('class' => 'form-control')) }}
</div>
<div class="col-md-12">
<h5>Price</h5>
{{ Form::number('price', null, array('class' => 'form-control')) }}
</div>
<div class="col-md-12">
<h5>Photo</h5>
{{ Form::file('photo', array('class' => 'form-control', 'id' => 'photo')) }}
</div>
<div class="col-md-12">
<h5>Type</h5>
<select name="type_id" id="type_id" class="form-control">
<option value="">-- Select --</option>
#foreach($types as $type)
<option value="{{$type->id}}">{{$type->name}}</option>
#endforeach
</select>
</div>
<div class="col-md-12 mt-2">
{{ Form::submit('Save', array('class' => 'btn btn-primary')) }}
</div>
</div>
{{ Form::close() }}
The "photo" => "air putih.jpg" should not be a string. It should have some more information regarding file.
I think the problem is in your blade file. Please check if you have used enctype='multipart/form-data' in your form tag.
EDIT
Change this
Image::make($photo)->resize(500, 500)->save($location);
To this
Image::make($photo->getRealPath())->resize(500, 500)->save($location);
Try to change this line
Image::make($photo)->resize(500, 500)->save($location);
Image::make($photo->getRealPath())->resize('200','200')->save($location);
Your realpath is false check config
You should try this:
Your view file like this:
{!! Form::open(['route' => 'menus.store', 'class' => 'form-horizontal', 'role' => 'form', 'method' => 'post','files'=>true]) !!}
<div class="row">
<div class="col-md-12">
<h5>Name</h5>
{{ Form::text('name', null, array('class' => 'form-control')) }}
</div>
<div class="col-md-12">
<h5>Price</h5>
{{ Form::number('price', null, array('class' => 'form-control')) }}
</div>
<div class="col-md-12">
<h5>Photo</h5>
{{ Form::file('photo', array('class' => 'form-control', 'id' => 'photo')) }}
</div>
<div class="col-md-12">
<h5>Type</h5>
<select name="type_id" id="type_id" class="form-control">
<option value="">-- Select --</option>
#foreach($types as $type)
<option value="{{$type->id}}">{{$type->name}}</option>
#endforeach
</select>
</div>
<div class="col-md-12 mt-2">
{{ Form::submit('Save', array('class' => 'btn btn-primary')) }}
</div>
</div>
{{ Form::close() }}
Your controller function like this:
use Input;
public function store(Request $request)
{
$this->validate($request, array(
'name' => 'required',
'price' => 'required|numeric',
'type_id' => 'required|numeric',
'photo' => 'required',
));
$item = new Menu;
$item->name = $request->input('name');
$item->price = $request->input('price');
$item->type_id = $request->input('type_id');
if ($request->hasFile('photo')) {
$photo = Input::file('photo');
$filename = 'MenuItem' . '-' . time() . '.' . $photo->getClientOriginalExtension();
$location = public_path('images/'. $filename);
$img = Image::make($photo->getRealPath());
$img->resize(500, 500, function ($constraint) {
$constraint->aspectRatio();
})->save($location);
$item->photo = $filename;
}
$item->save();
Session::flash('success', 'Menu Item Saved Successfully.');
return redirect()->back();
}

Laravel - Update Uploaded Files in Input File

I want to update my uploaded images, but as soon as I update 1 image the other images are removed why is that? I want to left them as what they are when they had been upload. help me please thanks.
Here is an image of the problem
Controller
Update, public function, here is where I put the logic of the code
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'fleet_image.*' => 'image|nullable|max:1999'
]);
$fleet = [];
if ($request->has('fleet_image'))
{
//Handle File Upload
foreach ($request->file('fleet_image') as $key => $file)
{
// Get FileName
$filenameWithExt = $file->getClientOriginalName();
//Get just filename
$filename = pathinfo( $filenameWithExt, PATHINFO_FILENAME);
//Get just extension
$extension = $file->getClientOriginalExtension();
//Filename to Store
$fileNameToStore = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->storeAs('public/fleet_images',$fileNameToStore);
array_push($fleet, $fileNameToStore);
}
$fileNameToStore = serialize($fleet);
}
else
{
$fileNameToStore='noimage.jpg';
}
if (count($fleet)) {
foreach ($fleet as $key => $value) {
$fleetContent = Fleet::find($id);
$fleetContent->title = $request->title[$key];
$fleetContent->description = $request->description[$key];
$implodedFleet = implode(' , ', $fleet);
if($request->hasFile('fleet_image')){
$fleetContent->fleet_image = $implodedFleet;
}
$fleetContent->save();
return redirect('/admin/airlineplus/fleets')->with('success', 'Content Updated');
}
}
return redirect('/admin/airlineplus/promotions')->with('success', 'Content Updated');
}
View, edit.blade.php
{!! Form::open(['action'=>['Admin\FleetsController#update',$fleet->id], 'method' => 'POST','enctype'=>'multipart/form-data', 'name' => 'add_name', 'id' => 'add_name']) !!}
<div class="table-responsive">
<table class="table table-bordered" id="dynamic_field">
<tr>
<td> {{Form::text('title[]', $fleet->title, ['class' => 'form-control', 'placeholder' => 'Enter a Title', 'id'=>"exampleFormControlFile1"])}}<br>
{{Form::textarea('description[]', $fleet->description, ['class' => 'form-control', 'placeholder' => 'Enter a Description'])}} <br>
<div class="card card-body col-md-8">
#foreach(explode(' , ' ,$fleet->fleet_image) as $content)
<img src="{{ asset('storage/fleet_images/' . $content) }}" style="width:50px;height:50px;"><br/>
{{ Form::file('fleet_image[]',['id'=>'exampleFormControlFile1']) }}<br/>
#endforeach
</div>
</td>
</tr>
</table>
{{Form::hidden('_method', 'PUT')}}
{{Form::submit('submit', ['class'=>'btn btn-primary', 'name'=>'submit'])}}
</div>
{!! Form::close() !!}
On your Controller
$fleet = array();
$fleetContent = Fleet::find($id);
if ($request->has('fleet_image')) {
for($i=0;$i<3;$i++){
if(isset($request->file('fleet_image')[$i])){
$filenameWithExt = $request->file('fleet_image')[$i]->getClientOriginalName();
//Get just filename
$filename = pathinfo( $filenameWithExt, PATHINFO_FILENAME);
//Get just extension
$extension = $request->file('fleet_image')[$i]->getClientOriginalExtension();
//Filename to Store
$fileNameToStore = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $request->file('fleet_image')[$i]->move('public/fleet_images',$fileNameToStore);
array_push($fleet, $fileNameToStore);
}else{
$fleetContentExplode = explode(',',$fleetContent->fleet_image);
array_push($fleet,$fleetContentExplode[$i]);
}
}
}
On your View File
{!! Form::open(['action'=>['Admin\FleetsController#update',$fleet->id], 'method' => 'POST','enctype'=>'multipart/form-data', 'name' => 'add_name', 'id' => 'add_name']) !!}
<div class="table-responsive">
<table class="table table-bordered" id="dynamic_field">
<tr>
<td> {{Form::text('title', $fleet->title, ['class' => 'form-control', 'placeholder' => 'Enter a Title', 'id'=>"exampleFormControlFile1"])}}<br>
{{Form::textarea('description', $fleet->description, ['class' => 'form-control', 'placeholder' => 'Enter a Description'])}} <br>
<div class="card card-body col-md-8">
#foreach(explode(' , ' ,$fleet->fleet_image) as $content)
<img src="{{ asset('storage/fleet_images/' . $content) }}" style="width:50px;height:50px;"><br/>
{{ Form::file('fleet_image[]',['id'=>'exampleFormControlFile1']) }}<br/>
#endforeach
</div>
</td>
</tr>
</table>
{{Form::hidden('_method', 'PUT')}}
{{Form::submit('submit', ['class'=>'btn btn-primary', 'name'=>'submit'])}}
</div>
{!! Form::close() !!}
NB:: I have just remove the array from your view input text

Laravel - the same validator works in one controller method but doesn't work in another

I have two simmilar forms, one for adding news to site, another to edit news:
{{ Form::open(array('action' => 'MyController#verifyAdminAddNews', 'files' => true)) }}
{{ Form::text('title', Form::old('title'), ['required' => 'required']) }}<br><br>
{{ Form::textarea('subtitle', Form::old('subtitle'), ['required' => 'required', 'style' => 'height:60px;']) }} <br><br>
{{ Form::textarea('text', Form::old('text'), ['required' => 'required']) }} <br><br>
{{ Form::file('image', '') }}
#if(isset($errormessage))
<div class="error-message"> {{ $errormessage }} </div>
#endif
{{ Form::submit('Pridať novinku', ['class' => 'form-control']) }}
{{ Form::close() }}
and:
{{ Form::open(array('action' => 'MyController#verifyAdminEditNews', 'class'=>'bg-grey width')) }}
{{ Form::text('title',$item->title, ['required' => 'required']) }}<br><br>
{{ Form::textarea('subtitle', $item->subtitle, ['required' => 'required', 'style' => 'height:60px;']) }}
{{ Form::textarea('text', $item->text, ['required' => 'required']) }} <br><br>
{{ Form::file('image', '') }}
#if(isset($errormessage))
<div class="error-message"> {{ $errormessage }}</div>
#endif
{{ Form::submit('Upraviť novinku', ['class' => 'form-control']) }}
{{ Form::close() }}
and in Controller are two methods for adding and editting news:
public function verifyAdminAddNews(){
if (is_object(DB::table('news')->orderBy('id', 'DESC')->first())) {
$newid = DB::table('news')->orderBy('id', 'DESC')->first()->id + 1; }
else { $newid = 0; }
// validate if file is image
$input = array('image' => Input::file('image'));
$rules = array('image' => 'image');
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
Input::flash();
return View::make('adminnadd', ['errormessage' => 'Chyba! Vybratý súbor nie je obrázok.'] );
} else {
if (Input::file('image')==null) {
DB::insert('INSERT INTO news (id, title, subtitle, text, imageurl) VALUES (?, ?, ?, ?, ?)',
array($newid, Input::get('title'), Input::get('subtitle'), Input::get('text'), 'none'));
} else {
$destination = 'uploadedimages';
$filename = 'image'.$newid;
Input::file('image')->move($destination, $filename);
DB::insert('INSERT INTO news (id, title, subtitle, text, imageurl) VALUES (?, ?, ?, ?, ?)',
array($newid, Input::get('title'), Input::get('subtitle'), Input::get('text'), $filename));
}
return View::make('adminnall',['items'=>DB::table('news')->get()]);
}
}
public function verifyAdminEditNews() {
$id = Session::get('editnewsid');
// validate if file is image
$input = array('image' => Input::file('image'));
$rules = array('image' => 'image');
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
Input::flash();
return View::make('adminnedit', ['errormessage' => 'Chyba! Vybratý súbor nie je obrázok.'] );
} else {
if (Input::file('image')==null) {
DB::table('news')->where('id', $id)->update(array('title' => Input::get('title'), 'subtitle' => Input::get('subtitle'), 'text'=>Input::get('text')));
} else {
$destination = 'uploadedimages';
$filename = 'image'.$id;
Input::file('image')->move($destination, $filename);
DB::table('news')->where('id', $id)->update(array('title' => Input::get('title'), 'subtitle' => Input::get('subtitle'), 'text'=>Input::get('text'), 'imageurl' => $filename ));
}
return View::make('adminnall',['items'=>DB::table('news')->get()]);
}
}
These methods have exactly the same Validator for validating if selected file is image. In verifyAdminAddNews it works right, returning error message back to view with form, when file is not image. But in verifyAdminEditNews validator will NOT fails when file is not image and will not return error message. How is this possible?
Oh, I forgot to add 'files' => 'true' to second form.

Can't upload file to server Laravel

I'm trying to add some products to my database and I have to upload photo of this product. I've made a controller and view but when I click Create I've got an error
Unable to create the "/uploads/products/" directory
Here is my code:
Controller
public function postAddProduct(){
$destinationPath = '';
$filename = '';
$newId = Product::max('id')+1;
$validator = Validator::make(Input::all(), array(
'name' => 'required',
'description' => 'required',
'partner_link' => 'required',
'image'=>'required'
));
if (Input::hasFile('image')) {
$file = Input::file('image');
$destinationPath = public_path().'/uploads/products/';
$filename = $newId.'.'.$file->getClientOriginalExtension();
$uploadSuccess = $file->move($destinationPath, $filename);
}
if($validator->passes()){
$product = new Product;
$product->name = Input::get('name');
$product->description = Input::get('description');
$product->category_id = Input::get('category');
$product->partner_link = Input::get('partner_link');
$product->photo = $filename;
$product->save();
return Redirect::back();
}else{
return Redirect::back()->withErrors($validator)->withInput();
}
}
View:
{{ Form::open(array('url'=>'user/admin/products/addd', 'files' => true, 'class'=>'col-md-4', 'style'=> 'float:none; margin: 0 auto', 'id'=>'register-form')) }}
<h2 class="form-signin-heading">Add Product</h2>
{{ Form::text('name', null, array('class'=>'form-control', 'placeholder'=>'Name')) }}
{{ Form::textarea('description', null, array('class'=>'form-control', 'placeholder'=>'Description')) }}
{{ Form::text('partner_link', null, array('class'=>'form-control', 'placeholder'=>'Partner link')) }}
{{Form::label('category', 'Category: ', array('class' => 'field-name'))}}
<select name="category">
<?php $i = 0; ?>
#foreach($categories as $category)
<optgroup label="{{$category['name']}}">
#foreach($category['subcategories'] as $sub)
<option value="{{$sub->id}}">{{$sub->name}}</option>
#endforeach
</optgroup>
#endforeach
</select>
<div class="clearfix"></div>
{{Form::file('image', array('style' => 'margin-bottom: 10px'))}}
{{ Form::submit('Add', array('class'=>'btn btn-large btn-primary btn-block'))}}
{{ Form::close() }}
Update
Current bootstrap/paths.php file:
return array(
'app' => __DIR__.'/../app',
'public' => __DIR__.'/../public',
'base' => __DIR__.'/..',
'storage' => __DIR__.'/../app/storage',
);
Sounds like the public/uploads/products folder does not exist, and Laravel does not have permission to create it.
Try create the folder manually, make sure Laravel has writable access to it by running chmod 775 public/uploads/products . Then try the code again.

Categories