Note: This tutorial code applies to Laravel version 5.1.
1. Overview
Dropzone is currently the best free file drag-and-drop library, it has many features and options so you can customize it in a variety of ways.
The Laravel Project Integration Dropzone is a bit tricky for inexperienced novices, so next I want you to show you the most elegant solution.
This tutorial will include the following:
- Automatic picture upload
- Remove a picture directly from the Dropzone preview with an AJAX request
- Upload Picture counter
- Save full size picture and icon size version
- Adjust picture size and encoding using intervention image package
- Save picture data to Database
- Generate a unique picture name on the server side
If you still need to upload or crop a picture, refer to the previous tutorial: Use the JQuery plugin Croppic + intervention image in Laravel 5 for picture uploading and cropping.
The complete code for this tutorial has been publicly available on GitHub: Https://github.com/codingo-me/dropzone-laravel-image-upload
The final demo is as follows:
2, the basic configuration of the project
Here we install a new Laravel app and create an. env file that contains database credential information.
We also download styles and script files from Https://github.com/enyo/dropzone/tree/master/dist, which are stored in Public/packages/dropzone.
Front end we still use bootstrap, related files are stored in Public/packages/bootstrap.
As mentioned above, we are going to use the intervention image extension package to process the uploaded image, and here we will be using the HTML helper function in the blade template, so we need to install the dependent dependency, install intervention image please refer to: in Laravel 5 Integrated intervention image for image creation, modification and compression processing, and installation of HTML please refer to: Laravel 5 using Htmlbuilder and Url::asset () introduced in the station or outside the CSS and JS files.
3. View
This tutorial contains only a single page for uploading pictures, although I prefer to separate the layout from the specific implementation page, we edit the layout file layout.blade.php as follows:
Image upload in Laravel 5.1 with Dropzone.js
{!! Html::style ('/packages/bootstrap/css/bootstrap.min.css ')!} {!! Html::style ('/assets/css/style.css ')!} {!! Html::script (' Https://code.jquery.com/jquery-2.1.4.min.js ')!} @yield (' head ' )Dropzone + Laravel
@yield (' content ') @yield (' footer ')
Next we create the view file that uploads the picture pages/upload.blade.php:
@extends (' layout ') @section (' head ') {!! Html::style ('/packages/dropzone/dropzone.css ')!} @stop @section (' footer ') {!! Html::script ('/packages/dropzone/dropzone.js ')!} {!! Html::script ('/assets/js/dropzone-config.js ')!} @stop @section (' content ')Images
{!! Form::open ([' url ' = + route (' Upload-post '), ' class ' = ' dropzone ', ' Files ' =>true, ' id ' = ' real-dropzone '])! Drop images in this area
{!! Form::close ()!!}
- Images is uploaded as soon as you drop them
- Maximum allowed size of image is 8MB
<title>Check</title>
Created with Sketch.
<title>Error</title>
Created with Sketch.
@stop
In the head section of the upload view we introduced the default style of Dropzone, in the footer section we passed the default JavaScript file and our own Dropzone configuration file.
The Content section contains two parts, the first is the upload form and then the hidden Picture preview area, I was downloaded from Dropzone official website Preview template code, in the configuration file use this template to tell Dropzone which HTML to upload Image preview.
4. Dropzone Configuration
View the full list of dropzone configuration items here, for this project I would like to upload a file from the dropzone, because then I do not need to loop through the file upload, the number of concurrent upload files is limited to 100 and each file size cannot exceed 8M.
Each picture preview corresponds to a delete link, click the link dropzone will trigger the Removedfile event, the event will create an upload/delete ajax request, if the response status code is 200, the corresponding picture counter is reduced.
var Photo_counter = 0;dropzone.options.realdropzone = {uploadmultiple:false, paralleluploads:100, MaxFilesize: 8, Previewscontainer: ' #dropzonePreview ', PreviewTemplate:document.querySelector (' #preview-template '). InnerHTML, Addremovelinks:true, Dictremovefile: ' Remove ', Dictfiletoobig: ' Image is bigger than 8MB ' and//the setting up O f the Dropzone init:function () {This.on ("Removedfile", function (file) {$.ajax ({type : ' POST ', url: ' Upload/delete ', data: {id:file.name}, DataType: ' HTML ', Success:function (data) {var rep = json.parse (data); if (Rep.code = =) {photo_counter--; $ ("#photoCounter"). Text ("(" + Photo_counter + ")"); } } }); } ); }, Error:function (file, response) {if ($.type (responSE) = = = "string") var message = response; Dropzone sends it ' s own error messages in string else var message = Response.message; File.previewElement.classList.add ("Dz-error"); _ref = File.previewElement.querySelectorAll ("[Data-dz-errormessage]"); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) {node = _ref[_i]; _results.push (node.textcontent = message); } return _results; }, Success:function (File,done) {photo_counter++; $ ("#photoCounter"). Text ("(" + Photo_counter + ")"); }}
The bottom of the profile if the upload succeeds picture counter is incremented.
5. Upload Logic
I am used to putting specific logic into the Repository class, which I use in this project Imagerepository class, which is stored in app/logic/image/imagerepository.php.
Currently this class only does two things, uploads a single file and deletes the specified file, and we inject the entire repository class into the Imagecontroller:
image = $imageRepository; } Public Function Getupload () { return view (' Pages.upload '); } Public Function Postupload () { $photo = Input::all (); $response = $this->image->upload ($photo); return $response; } Public Function Deleteupload () { $filename = input::get (' id '); if (! $filename) { return 0; } $response = $this->image->delete ($filename); return $response; }}
So I need three routes for this controller: Show upload form, upload, and delete requests:
Route::get ('/', [' as ' = ' upload ', ' uses ' = ' imagecontroller@getupload ']); Route::p ost (' Upload ', [' as ' = ' upload-post ', ' uses ' = ' imagecontroller@postupload ']); Route::p ost (' Upload/delete ', [' as ' = ' upload-remove ', ' uses ' = ' imagecontroller@deleteupload ']);
The Imagecontroller Postupload method forwards the user upload request to the upload method corresponding to the Imagerepository class. This upload method first validates the input, then assigns a unique file name to the upload file, then saves the original size picture to the specified directory, saves the icon size picture to a different directory, and saves it to the database so laravel can track the image upload record. To do this we need to create a migration file and run the migration command:
Increments (' id '); $table->text (' original_name '); $table->text (' filename '); $table->timestamps (); }); } /** * Reverse the migrations. * * @return void * /Public Function down () { Schema::d rop (' images ');} }
I already mentioned it. The upload file will be saved in two sizes, in addition to the possibility to generate thumbnails and encode images, to implement these functions, we need to use the intervention image expansion pack:
Fails ()) {return Response::json ([' error ' = ' = ') ' Message ' = $validator ->messages ()->first (), ' code ' = 400], 400); } $photo = $form _data[' file ']; $originalName = $photo->getclientoriginalname (); $ORIGINALNAMEWITHOUTEXT = substr ($originalName, 0, strlen ($originalName)-4); $filename = $this->sanitize ($ORIGINALNAMEWITHOUTEXT); $allowed _filename = $this->createuniquefilename ($filename); $FILENAMEEXT = $allowed _filename. JPG '; $uploadSuccess 1 = $this->original ($photo, $FILENAMEEXT); $uploadSuccess 2 = $this->icon ($photo, $FILENAMEEXT); if (! $uploadSuccess 1 | |! $uploadSuccess 2) {return Response::json ([' Error ' = True, ' Message ' = ' Server error while uploading ', ' code ' = 500], 500); } $sessionImage = new Image; $Sessionimage->filename = $allowed _filename; $sessionImage->original_name = $originalName; $sessionImage->save (); return Response::json ([' ERROR ' = False, ' code ' = 200], 200); The Public Function Createuniquefilename ($filename) {$full _size_dir = config::get (' images.full_size '); $full _image_path = $full _size_dir. $filename. '. jpg '; if (file::exists ($full _image_path)) {//Generate token for image $imageToken = substr (sh A1 (Mt_rand ()), 0, 5); Return $filename. '-' . $imageToken; } return $filename; }/** * Optimize Original Image */Public Function Original ($photo, $filename) {$manager = new Imagemanager (); $image = $manager->make ($photo)->encode (' jpg ')->save (Config::get (' images.full_size '). $filename); return $image; }/** * Create Icon from Original */ Public function icon ($photo, $filename) {$manager = new Imagemanager (); $image = $manager->make ($photo)->encode (' jpg ')->resize ($, NULL, function ($constraint) {$constraint Aspectratio ();}) ->save (Config::get (' images.icon_size '). $filename); return $image; }/** * Delete Image from Session folder, based on original filename */Public function Delete ($originalFil ename) {$full _size_dir = config::get (' images.full_size '); $icon _size_dir = config::get (' images.icon_size '); $sessionImage = Image::where (' original_name ', ' like ', $originalFilename)->first (); if (empty ($sessionImage)) {return Response::json ([' error ' = = True, ' Co De ' = 400], 400); } $full _path1 = $full _size_dir. $sessionImage->filename. '. jpg '; $full _path2 = $icon _size_dir. $sessionImage->filename. '. jpg '; if (File::exists ($fULL_PATH1) {File::d elete ($full _path1); } if (File::exists ($full _path2)) {File::d elete ($full _path2); } if (!empty ($sessionImage)) {$sessionImage->delete (); } return Response::json ([' ERROR ' = False, ' code ' = 200], 200); } function Sanitize ($string, $force _lowercase = true, $anal = False) {$strip = array ("~", "'", "!", "@", "#" , "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", "}", "\ \", "|", ";", ":", "\" "," "", "" " , "'", "" "," "", "–", "-", "â €", "â €" ",", "," < ",". "," > ","/","? "); $clean = Trim (Str_replace ($strip, "", Strip_tags ($string))); $clean = preg_replace ('/\s+/', "-", $clean); $clean = ($anal)? Preg_replace ("/[^a-za-z0-9]/", "", $clean): $clean; Return ($force _lowercase)? (Function_exists (' Mb_strtolower '))? Mb_strtolower ($clean, ' UTF-8 '): Strtolower ($clean): $clean; }}
The Upload method validates the field rules specified in the image model, and the rule is currently limited to the extension of the uploaded image.
After the upload method we use the Reateuniquefilename method to return a unique file name for the picture.
When the unique file name is returned, we pass the picture and the corresponding file name to the original method, which is responsible for saving the full size picture, we use the icon method to handle the image of the small size icon.
After both dimensions have been saved, a new record is created in the picture table images.
You may have noticed that I put the image upload directory in the configuration file, of course you can customize the directory or directly use the Laravel built-in method.
Env (' upload_full_size '), ' icon_size ' = env (' upload_icon_size '),];
For your app to work, you'll also need to copy the. env.example file to an. env file and set the appropriate configuration values. Note that the upload directory for the last two configuration items needs to be/ended with my local configuration as an example:
Upload_full_size=f:/xampp/htdocs/nonfu/dropzone-laravel-image-upload/public/images/full_size/upload_icon_size= f:/xampp/htdocs/nonfu/dropzone-laravel-image-upload/public/images/icon_size/
The Delete method receives the file name and checks whether the database contains it, and then if the corresponding file exists in the specified directory, the picture is deleted if both items match.
To make it easier to upload images using Dropzonejs, you can use the Laravel extension package Dropzoner.
Disclaimer: This article is for translation, original: Https://tuts.codingo.me/laravel-5-1-and-dropzone-js-auto-image-uploads-with-removal-links