In Laravel5.1, image drag/drop upload and deletion are implemented based on Dropzone. js.

Source: Internet
Author: User
In Laravel5.1, image drag/drop upload and deletion are implemented based on Dropzone. js. note: This tutorial code applies to Laravel 5.1.



1. Overview

Dropzone is currently the best free drag/drop file Upload Library. it has many features and options so that you can customize it in multiple ways.

Integrating Dropzone with Laravel is a bit tricky for beginners who are not experienced, so I want to show you the most elegant solution.

This tutorial includes the following content:

  • Automatic image Upload
  • Remove images directly from Dropzone preview using Ajax requests
  • Upload image counters
  • Save the full size image and icon size version
  • Use the Intervention Image package to adjust the Image size and encoding
  • Save image data to database
  • Generate a unique image name on the server

If you still need to upload or crop images, refer to the previous tutorial: Use the jQuery plug-in Croppic + Intervention Image in Laravel 5 to upload and crop images.

The complete code for this tutorial is published on GitHub: https://github.com/codingo-me/dropzone-laravel-image-upload

The final demonstration is as follows:

2. basic project configuration

Here we install a new Laravel application and create a. env file containing the database creden.

We also need to download style and script files from the https://github.com/enyo/dropzone/tree/master/dist that are stored in public/packages/dropzone.

We still use Bootstrap at the front end, and the relevant files are stored in public/packages/bootstrap.

As mentioned above, we need to use the Intervention Image extension package to process uploaded images, and here we will use html auxiliary functions in the Blade template. Therefore, we need to install related dependencies. to install Intervention Image, refer: intervention Image is integrated in Laravel 5 to create, modify, and compress images. for details about how to install html, see HtmlBuilder and URL: asset () in Laravel 5 () introduce css and js files on or off the site.

3. View

This tutorial only contains a single page for uploading images. although I prefer to separate the layout from the specific implementation page, we edit the layout file layout. blade. php as follows:

{!! 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

        

                
Upload
            
        
    
    

@yield ('content')
@yield ('footer')
Next we create a view file pages / upload.blade.php for uploading images:

@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 are uploaded as soon as you drop them
                    
Maximum allowed size of image is 8MB
                
            
        
    
        
            

            
                


                

            
            

            

            
                            

            
                            

        
    
    @stop
In the head section of the upload view, we introduced Dropzone's default style. In the footer section, we passed the default JavaScript file and our own Dropzone configuration file.

The content part consists of two parts. The first is the upload form and then the hidden image preview area. I downloaded the preview template code from the official website of Dropzone, and used this template in the configuration file to tell Dropzone which piece of HTML is used to upload the image preview.

4.Dropzone configuration
See the complete list of Dropzone configuration items for reference. For this project, I want to upload files one by one from Dropzone, because then I do n’t need to loop through file uploads. The number of concurrent upload files is limited to 100 and each file size cannot exceed 8M .

Each image preview corresponds to a delete link. Clicking on the link Dropzone will trigger the removedfile event. This event will create an upload / delete Ajax request. If the response status code is 200, the corresponding image counter will decrease.

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', // The setting up of 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 == 200) {photo_counter--; $ ("# photoCounter"). text ("(" + photo_counter + ")");}}});});}, error: function (file, response) { if ($. type (respon se) === "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 counter at the bottom of the configuration file is incremented if the upload is successful.

5.Upload logic
I am used to putting specific logic into the Repository class. In this project, I use the ImageRepository class, which is stored in app / Logic / Image / ImageRepository.php.

Currently this class does only two things, upload a single file and delete the specified file. 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 for this controller I need three routes: display upload form, upload and delete request:

Route :: get ('/', ['as' =>' upload ',' uses' => 'ImageController @ getUpload']); Route :: post ('upload', ['as' =>' upload- post ',' uses' => 'ImageController @ postUpload']); Route :: post ('upload / delete', ['as' =>' upload-remove ',' uses' => 'ImageController @ deleteUpload'] );
ImageController's postUpload method forwards user upload requests to the upload method corresponding to the ImageRepository class. This upload method first validates the input, then assigns a unique file name to the uploaded file, and then saves the original size image to the specified directory, while saving the icon size image to other directories, and also saves to the database so that Laravel can track the image upload recording. 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 :: drop ('images');}}
I have mentioned After uploading the file will be saved in two sizes. In addition, you may also need to generate thumbnails and encode pictures. To achieve these functions, we need to use the Intervention Image extension package:

fails ()) {return Response :: json (['error' => true, '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'; $ uploadSuccess1 = $ this-> original ($ photo, $ filenameExt); $ uploadSuccess2 = $ this-> icon ($ photo, $ filenameExt); if (! $ uploadSuccess1 ||! $ uploadSuccess2) {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);} 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 (sha1 (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 (200, 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 ($ originalFilename) {$ 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, 'code' => 400], 400);} $ full_path1 = $ full_size_dir. $ sessionImage-> filename . '.jpg'; $ full_path2 = $ icon_size_dir. $ sessionImage-> filename. '.jpg'; if (File :: exists ($ full_path1)) {File :: delete ($ full_path1);} if (File :: exi sts ($ full_path2)) {File :: delete ($ 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): $ clea n;}}
The upload method validates the field rules specified in the Image model. Currently, this rule only restricts the extension of uploaded images.

After the upload method we use the reateUniqueFilename method to return a unique filename for the image.

When the unique file name is returned, we pass the image and the corresponding file name to the original method. This method is responsible for saving the full-size image, and we use the icon method to process the small-size icon image.

After the two size images are saved, a new record is created in the image table images.

You may have noticed that I stored the image upload directory in the configuration file. Of course, you can customize the storage directory or use Laravel's built-in methods directly.

 env ('UPLOAD_FULL_SIZE'), 'icon_size' => env ('UPLOAD_ICON_SIZE'),];
For the app to work properly, you also need to copy the .env.example file to the .env file and set the appropriate configuration values. Note that the upload directory of the last two configuration items needs to end with /. Take 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 it is contained in the database, and then the corresponding file exists in the specified directory. If both items match, the picture will be deleted.

To make it easier to upload images with DropzoneJS, you can use the Laravel extension package Dropzoner.

Disclaimer: This article is a translation, the original text: https://tuts.codingo.me/laravel-5-1-and-dropzone-js-auto-image-uploads-with-removal-links

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.