3.1.1 Thêm thư viện dropzone upload ảnh, thêm bảng tickets và sử dụng laravel-medialibrary (ok)

Bản chỉnh sửa và rút gọn

C:\xampp82\htdocs\testnet\database\migrations\2023_05_20_180644_create_tickets_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('tickets', function (Blueprint $table) {
      $table->id();
      $table->string('title');
      $table->longText('content')->nullable();
      $table->softDeletes();
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('tickets');
  }
};

C:\xampp82\htdocs\testnet\app\Models\Ticket.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class Ticket extends Model implements HasMedia
{
  use HasFactory, SoftDeletes, InteractsWithMedia;
  public $table = 'tickets';
  protected $appends = [
    'attachments',
  ];
  protected $dates = [
    'created_at',
    'updated_at',
    'deleted_at',
  ];
  protected $fillable = [
    'title',
    'content',
    'created_at',
    'updated_at',
    'deleted_at',
  ];
  public static function boot()
  {
    parent::boot();
  }
  public function registerMediaConversions(Media $media = null): void
  {
    $this->addMediaConversion('thumb')->width(50)->height(50);
  }
  public function getAttachmentsAttribute()
  {
    return $this->getMedia('attachments');
  }
}

C:\xampp82\htdocs\testnet\app\Http\Controllers\Traits\MediaUploadingTrait.php

<?php
namespace App\Http\Controllers\Traits;
use Illuminate\Http\Request;
trait MediaUploadingTrait
{
  public function storeMedia(Request $request)
  {
    // Validates file size
    if (request()->has('size')) {
      $this->validate(request(), [
        'file' => 'max:' . request()->input('size') * 1024,
      ]);
    }
    // If width or height is preset - we are validating it as an image
    if (request()->has('width') || request()->has('height')) {
      $this->validate(request(), [
        'file' => sprintf(
          'image|dimensions:max_width=%s,max_height=%s',
          request()->input('width', 100000),
          request()->input('height', 100000)
        ),
      ]);
    }
    $path = storage_path('tmp/uploads');
    try {
      if (!file_exists($path)) {
        mkdir($path, 0755, true);
      }
    } catch (\Exception $e) {
    }
    $file = $request->file('file');
    $name = uniqid() . '_' . trim($file->getClientOriginalName());
    $file->move($path, $name);
    return response()->json([
      'name'          => $name,
      'original_name' => $file->getClientOriginalName(),
    ]);
  }
}

C:\xampp82\htdocs\testcom\app\Http\Controllers\TicketController.php

<?php
namespace App\Http\Controllers;
use App\Models\Ticket;
use Illuminate\Http\Request;
use App\Http\Controllers\Traits\MediaUploadingTrait;
class TicketsController extends Controller
{
  use MediaUploadingTrait;
  /**
   * Display a listing of the resource.
   *
   * @return \Illuminate\Http\Response
   */
  public function index()
  {
    //
  }
  /**
   * Show the form for creating a new resource.
   *
   * @return \Illuminate\Http\Response
   */
  public function create()
  {
    return view('tickets.create');
  }
  /**
   * Store a newly created resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @return \Illuminate\Http\Response
   */
  public function store(Request $request)
  {
    $request->validate([
      'title'         => 'required',
      'content'       => 'required'
    ]);
    $ticket = Ticket::create($request->all());
    foreach ($request->input('attachments', []) as $file) {
      $ticket->addMedia(storage_path('tmp/uploads/' . $file))->toMediaCollection('attachments');
    }
    return redirect()->back()->withStatus('Your ticket has been submitted, we will be in touch. You can view ticket status <a href="' . route('tickets.show', $ticket->id) . '">here</a>');
  }
  /**
   * Display the specified resource.
   *
   * @param  \App\Models\Ticket  $ticket
   * @return \Illuminate\Http\Response
   */
  public function show(Ticket $ticket)
  {
    //
  }
  /**
   * Show the form for editing the specified resource.
   *
   * @param  \App\Models\Ticket  $ticket
   * @return \Illuminate\Http\Response
   */
  public function edit(Ticket $ticket)
  {
    //
  }
  /**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\Models\Ticket  $ticket
   * @return \Illuminate\Http\Response
   */
  public function update(Request $request, Ticket $ticket)
  {
    //
  }
  /**
   * Remove the specified resource from storage.
   *
   * @param  \App\Models\Ticket  $ticket
   * @return \Illuminate\Http\Response
   */
  public function destroy(Ticket $ticket)
  {
    //
  }
}

C:\xampp82\htdocs\testnet\routes\web.php

<?php
use App\Http\Controllers\BannerController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\MediaController;
use App\Http\Controllers\MenuController;
use App\Http\Controllers\UsersController;
use App\Http\Controllers\MenuElementController;
use App\Http\Controllers\RolesController;
use App\Http\Controllers\TicketsController;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::group(['middleware' => 'get.menu'], function () {
  Route::get('/', function () {
    return view('dashboard.homepage');
  });
  Auth::routes();
  Route::get('/home', [HomeController::class, 'index'])->name('home');
  Route::group(['middleware' => ['role:admin']], function () {
    Route::get('/test-role-admin', function () {
      echo "Hello Admin";
    });
    Route::resource('users', UsersController::class)->except(['create', 'store']);
    Route::resource('roles', RolesController::class);
  });
  Route::group(['prefix' => 'menu/menu'], function () {
    Route::get('/', [MenuController::class, 'index'])->name('menu.menu.index');
    Route::get('show/{id}', [MenuController::class, 'show'])->name('menu.menu.show');
    Route::get('edit/{id}', [MenuController::class, 'edit'])->name('menu.menu.edit');
    Route::post('update', [MenuController::class, 'update'])->name('menu.menu.update');
    Route::get('create', [MenuController::class, 'create'])->name('menu.menu.create');
    Route::post('store', [MenuController::class, 'store'])->name('menu.menu.store');
    Route::post('destroy/{id}', [MenuController::class, 'destroy'])->name('menu.menu.destroy');
  });
  Route::group(['prefix' => 'media'], function () {
    Route::get('/', [MediaController::class, 'index'])->name('media.folder.index');
  });
  Route::resource('tickets', TicketsController::class);
  Route::post('tickets/media', [TicketsController::class, 'storeMedia'])->name('tickets.storeMedia');
});

Last updated