I’m currently working on a Laravel 5 application which includes a restricted administration console used to manage products sold through an online catalog. Each product includes a name, SKU, price, description, and image. The image is uploaded using the Form::file
helper made available through theLaravelCollective/html package, validated alongside the other form inputs using a Laravel 5 form request (see this tutorial if you’re not familiar with form requests), and if valid, stored in a special directory. In this blog post I’ll show you how this was implemented.
Let’s begin with a simplified version of the form used in my project. Again, this uses theLaravelCollective/html package’s form helpers to generate the various form fields:
{!! Form::open(
array(
'route' => 'admin.products.store',
'class' => 'form',
'novalidate' => 'novalidate',
'files' => true)) !!}
<div class="form-group">
{!! Form::label('Product Name') !!}
{!! Form::text('name', null, array('placeholder'=>'Chess Board')) !!}
</div>
<div class="form-group">
{!! Form::label('Product SKU') !!}
{!! Form::text('sku', null, array('placeholder'=>'1234')) !!}
</div>
<div class="form-group">
{!! Form::label('Product Image') !!}
{!! Form::file('image', null) !!}
</div>
<div class="form-group">
{!! Form::submit('Create Product!') !!}
</div>
{!! Form::close() !!}
</div>
Specific to the matter of file uploading there are two key characteristics of this form you’ll need to keep in mind when implementing your own uploader:
- The
Form::open
method sets the'files' => true
attribute. This results in the form data being encoded as “multipart/form-data”, which is required when files will be included as form data. - The
Form::file
helper is used to generate the file upload control.
When rendered to the browser the form looks like this:
As you can see, the form is submitted to a route named admin.products.store
. As is typical of any Laravel 5 application, the submitted form data is first routed through a form request. The validation rules are found in the form request’s rules()
method. Here’s an example which validates the supplied image to ensure one is present and that it is specifically a PNG (image file):
public function rules()
{
return [
'name' => 'required',
'sku' => 'required|unique:products,sku,' . $this->get('id'),
'image' => 'required|mimes:png'
];
}
You can validate uploads using plenty of other approaches such as ensuring it is a Word document or PDF. See the Laravel documentation for more information. This request is passed into theAdmin/ProductController.php
’s store
method, which looks like this:
public function store(ProductRequest $request)
{
$product = new Product(array(
'name' => $request->get('name'),
'sku' => $request->get('sku')
));
$product->save();
$imageName = $product->id . '.' .
$request->file('image')->getClientOriginalExtension();
$request->file('image')->move(
base_path() . '/public/images/catalog/', $imageName
);
return \Redirect::route('admin.products.edit',
array($product->id))->with('message', 'Product added!');
}
In this action we first save the product, and then process the image. There are plenty of different approaches to processing the uploaded image; I’m keeping this simple and just saving the image using a name matching the product ID, so for instance if the saved product using the ID 42 then the associated uploaded image will be named 42.png
. The image name is first created (and stored in $imageName
) and then it is moved into the application’s /public/images/catalog
directory.
Believe it or not, uploading an image using Laravel 5 is really that simple!