-
move your validation to before storing images
-
change move() to storeAs
-
you don't handle images on update method?
-
simplify your code by un-nesting the ifs and extract the common operations to a function
Mar 29, 2020
8
Level 1
File upload for 3 product images
Hi All,
I have recently began working on uploading images to my site. This is my first time doing this so not sure what I can do fully or not. I followed a tutorial on youtube to get it working for my auth user however now I am trying to get it working for my products but it is giving this error.
Call to a member function getClientOriginalExtension() on null
form
@extends('layouts.app')
@section('page_title')
Create Product
@endsection
@section('page_heading')
<h2>Create Product</h2>
@endsection
@section('content')
<div class="header">Create a Product</div>
<form class="form" action="/product/{product}/create" enctype="multipart/form-data" method="POST">
<fieldset>
@csrf
<div class="notification is-warning">
<ul>
@error('make')<li>{{ $message }}</li>@enderror
@error('model')<li>{{ $message }}</li>@enderror
@error('watt')<li>{{ $message }}</li>@enderror
@error('genre')<li>{{ $message }}</li>@enderror
@error('description')<li>{{ $message }}</li>@enderror
@error('star_rating')<li>{{ $message }}</li>@enderror
@error('image_1')<li>{{ $message }}</li>@enderror
@error('image_2')<li>{{ $message }}</li>@enderror
@error('image_3')<li>{{ $message }}</li>@enderror
</ul>
</div>
<div class="holder">
<label class="left-form" for="make">Make</label>
<input class="right-form" id="make" name="make" class="input" type="text" placeholder="" autofocus>
</div>
<div class="holder">
<label class="left-form" for="model">Model</label>
<input class="right-form" id="model" name="model" class="input" type="text" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="watt">Watt</label>
<input class="right-form" id="watt" name="watt" class="input" type="text" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="genre">Genre</label>
<input class="right-form" id="genre" name="genre" class="input" type="text" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="description">Description</label>
<input class="right-form" id="description" name="description" class="input" type="text" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="star_rating">Star Rating</label>
<input class="right-form" id="star_rating" name="star_rating" class="input" type="text" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="image_1">Image One</label>
<input class="right-form" id="image_1" name="image_1" class="input" type="file" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="image_2">Image Two</label>
<input class="right-form" id="image_2" name="image_2" class="input" type="file" placeholder="">
</div>
<div class="holder">
<label class="left-form" for="image_3">Image Three</label>
<input class="right-form" id="image_3" name="image_3" class="input" type="file" placeholder="">
</div>
<div class="submit">
<button class="reset-reg" type="submit">Save Your Changes</button>
</div>
</fieldset>
</form>
@endsection
controller
<?php
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
class ProductsController extends Controller
{
public function __construct()
{
$this -> middleware('auth')->except('index','show');
}
const RULES = [
'make' => 'required|min:1|max:64',
'model' => 'required|min:1|max:256',
'watt' => 'required|min:1|max:256',
'genre' => 'required|min:1|max:256',
'description' => 'required|min:1|max:256',
'star_rating' => 'required|min:1|max:256',
'image_1' => 'required|image|mimes:jpg,jpeg,bmp,svg,png|max:5000',
'image_2' => 'required|image|mimes:jpg,jpeg,bmp,svg,png|max:5000',
'image_3' => 'required|image|mimes:jpg,jpeg,bmp,svg,png|max:5000',
];
const MESSAGES = [
'make.required' => 'The make of Amplifier is required.',
'model.required' => 'The model has to have a value.',
'watt.required' => 'The input field but be an integer.',
'genre.required' => 'The Amplifier must have a genre.',
'description.required' => 'The you must give a brief description of the amplifier.',
'star_rating.required' => 'Please choose a star rating for the product.',
'image_1.required' => 'You need to have 3 images for a product.',
'image_2.required' => 'You need to have 3 images for a product.',
'image_3.required' => 'You need to have 3 images for a product.',
];
const PRODUCTS_PER_PAGE = 5;
public function index (){
$products = Product::paginate(self::PRODUCTS_PER_PAGE);
return view ('product.products') -> with (['products' => $products]);
}
public function edit(Request $request, Product $product)
{
$product -> update (request (['product']));
return view ('product.edit') -> with (['product' => $product]);
}
public function update (Request $request, Product $product)
{
$request -> validate (self::RULES, self::MESSAGES);
$product -> update ($request -> only('make','model','watt','genre','updated_at','star_rating','description'));
return redirect () -> action ('ProductsController@index');
}
public function create(Request $request){
return view ('product.create');
}
public function store (Request $request){
if(request()->has('image_1')){
$productimageone = request()->file('image_1');
$productimageonename = time() .'.'. $productimageone -> getClientOriginalExtension();
$prodimgsaveone = public_path('/uploads/avatars/');
$productimageone -> move($prodimgsaveone, $productimageonename);
if(request()->has('image_2')){
$productimagetwo = request() -> file ('image_2');
$productimagetwoname = time() .'.'.$productimagetwo -> getClientOriginalExtension();
$prodimgsavetwo = public_path('/uploads/products/');
$productimagetwo -> move($prodimgsavetwo, $productimagetwoname);
if(request()->has('image_3')){
$productimagethree = request() -> file ('image_3');
$productimagethreename = time() .'.'.$productimagethree -> getClientOriginalExtension();
$prodimgsavethree = public_path('/uploads/products/');
$productimagethree -> move($prodimgsavethree, $productimagethreename);
$request -> validate (self::RULES, self::MESSAGES);
$attributes = request (['make','model','watt','genre', 'description','star_rating','image_1','image_2','image_3']);
$attributes ['genre_id'] = 0;
$attributes ['image_1'] = '/uploads/avatars/'.$productimageone;
$attributes ['image_2'] = '/uploads/avatars/'.$productimagetwo;
$attributes ['image_3'] = '/uploads/avatars/'.$productimagethree;
Product::create ($attributes);
return redirect () -> action ('ProductsController@index');
}
}
}
}
public function destroy(Product $product)
{
$product -> delete();
return redirect () -> action ('ProductsController@index');
}
public function search (Request $request, Product $product)
{
$query = $request -> input ('query');
$product = Product::where ('make','like',"%$query%")->paginate(self::PRODUCTS_PER_PAGE);
return view('product.search') -> with ('product', $product);
}
}
model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'make',
'model',
'watt',
'genre',
'updated_at',
'description',
'star_rating',
'image_1',
'image_2',
'image_3',
];
public function comments()
{
return $this->hasMany(Comment::class);
}
}
Any help on this would greatly appreciated.
Thank you for looking, Ben :)
Level 75
Just use
$file->move($destinationPath, (string) $arrname[$k]);
// your case
$productimageone->move($prodimgsaveone, $productimageonename);
You had spaces. Nothing special about storeas by the way, it's just using:
move_uploaded_file($this->getPathname(), $target);
Just like php.
1 like
Please or to participate in this conversation.