Laravel’ de DropzoneJS Kullanarak Sürükle Bırak ile Çoklu Dosya/Resim Yükleme

Web uygulamalarında günümüzde kullanıcı deneyimine büyük önem veriliyor. Form doldurmak kullanıcılara sıkıcı gelen bir aktivitedir. Bu nedenle form doldurmayı kolaylaştırmak uygulama geliştiricisin görevidir. Bu yazıda Laravel ile geliştirilen uygulamalarda, kullanıcıların kolay bir şekilde birden fazla dosya ve resimi nasıl yükleyebileceğini anlatacağım.

Aşağıda anlatacağım örnekte javascriptin dropzoneJS kütüphanesini kullanacağım. DropzoneJS kütüphanesi basit, hafif ve ilerleme barı bulunan kullanışlı bir kütüphanedir.

1.) Laravel Projesinin Kurulumu

Eğer bilgisayarınızda composer yüklü ise aşağıdaki kod satırını terminalde çalıştırarak laravel projenizi oluşturabilirsiniz.

composer create-project --prefer-dist laravel/laravel dropzone-laravel-project

2.) MySQL Veritabanı Ayarları

Laravel projesinin .env dosyasında Mysql veritabanı ayarlarımızı tanımlıyoruz.

DB_CONNECTION=mysql 
DB_HOST=127.0.0.1  
DB_PORT=3306  
DB_DATABASE=myLaravelDb 
DB_USERNAME=root
DB_PASSWORD=

3.) Model Oluşturulması ve Veritabanında Tablonun Oluşturulması

İlk önce ImageGallery adında modelimizi ve migration dosyasını aşağıdaki kod satırını çalıştırarak oluştururuz.

php artisan make:model ImageGallery -m

2021_07_19_144128_create_image_galleries_table.php adında dosyamız oluştu. Bu dosyayı açarak veri tabanında oluşturacağımız kolonlarını tanımlarız.

class CreateImageGalleriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('image_galleries', function (Blueprint $table) {
            $table->id();
            $table->string('original_filename');
            $table->string('filename_path');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('image_galleries');
    }
}

Dosyayı düzenledikten sonra migrate ederiz.

php artisan migrate

4.) Route’ ları Tanımla

routes\web.php dosyasında route’ larımız tanımlıyoruz. İlk route kullanıcının karşısına çıkacak arayüzdür. İkinci route’ da dosyamızı post edeceğimiz url’ i üçüncüsünde kullanıcı yüklediği dosyayı anında sildiğinde çalışacak url’ i tanımlıyoruz.

// ============== DropZone Example ==================
Route::get('/dropzone-ui', [ UploadController::class, 'dropzoneUI' ])->name('front.dropzone-ui');
Route::post('/upload', [ UploadController::class, 'uploadDropzoneFile' ])->name('front.upload');
Route::post('/file-destroy', [ UploadController::class, 'destroyFile' ])->name('front.file-destroy');

5.) Blade View Dosyasının Oluşturulması

Aşağıdaki resimdeki görüldüğü gibi dropzone-upload.blade.php adında view dosyamızı oluşturuyoruz.

Klasör yapısı

Blade dosyasına bootstrap, jquery ve dropzone javascript kütüphanelerini ekliyoruz.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{asset('assets/css/bootstrap.css')}}">
  	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/min/dropzone.min.css">
</head>
<body>

<div class="container">
    <h2>Dropzone Example</h2>
    <div class="row justify-content-md-center">
        <div class="col-12">
            <div class="dropzone" id="file-dropzone"></div>
        </div>
    </div>
</div>

<script src="{{ asset('assets/js/jquery.js')}}"></script>
<script src="{{ asset('assets/js/bootstrap.js')}}"></script>
<script src="{{ asset('assets/js/bootstrap.bundle.js')}}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/min/dropzone.min.js"></script>
<script>
    Dropzone.options.fileDropzone = {
      url: '{{ route('front.upload') }}',
      acceptedFiles: ".jpeg,.jpg,.png,.gif",
      addRemoveLinks: true,
      maxFilesize: 8,
      headers: {
      'X-CSRF-TOKEN': "{{ csrf_token() }}"
      },
      removedfile: function(file)
      {
        var name = file.upload.filename;
        $.ajax({
          type: 'POST',
          url: '{{ route('front.file-destroy') }}',
          data: { "_token": "{{ csrf_token() }}", name: name},
          success: function (data){
              console.log("File has been successfully removed!!");
          },
          error: function(e) {
              console.log(e);
          }});
          var fileRef;
          return (fileRef = file.previewElement) != null ?
          fileRef.parentNode.removeChild(file.previewElement) : void 0;
      },
      success: function (file, response) {
        console.log(file);
      },
    }
  </script>

</body>
</html>

6-) Controller Oluşturulması

Aşağıdaki kod satırını çalıştırarak controller’ ı oluşturuyoruz.

php artisan make:controller UploadController

app\Http\Controllers\UploadController.php dosyasında metodlarımızı yazıyoruz.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\ImageGallery;

class UploadController extends Controller
{
    private $photos_path;

    public function __construct()
    {
        $this->photos_path = public_path('/uploads');
    }

    /** 
 * Generate Upload View 
 * 
 * @return void 

 */  

  public  function dropzoneUI()  
  {  
      return view('front.dropzone-upload');  
  }  

/** 
 * File Upload Method 
 * 
 * @return void 
 */  

  public  function uploadDropzoneFile(Request $request)  
  {  

    if (!is_dir($this->photos_path)) {
        mkdir($this->photos_path, 0777);
    }

    if ($request->file('file')) {
        $file = $request->file('file');
        $fileName = $file->getClientOriginalName();
        $filePath = time().'.'.$file->getClientOriginalName();
        $file->move(public_path('uploads'), $filePath);
      }

        $imageUpload = new ImageGallery;
        $imageUpload->original_filename =  $fileName;
        $imageUpload->filename_path = $filePath;
        $imageUpload->save();
    return response()->json(['success'=>$fileName]);  
  }

  public function destroyFile(Request $request)
  {
      $filename =  $request->get('name');
      ImageGallery::where('original_filename',$filename)->delete();
      $path = public_path('uploads/').$filename;
      if (file_exists($path)) {
          unlink($path);
      }
      return response()->json(['success'=>$filename]);
  } 
}

Projemizi çalıştırdığımızda aşağıdaki gibi resimleri sürükleyerek dosyalarımızı servera yükleyebiliriz.

Kullanıcı arayüzü
Veritabanı görünüşü

Başarılar …