
Rich text editor did not had image upload feature – Here’s how I fixed it
The rich text editor I was using did not had image upload feature. It only allow URL of image to be posted in post’s content. So I created my own file manager module. I was uploading files on my Laravel website and then use their links in my rich text editor.
1. Migration
Here is the migration I used to manage files.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('files', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable(); // custom name
$table->string('file_path')->nullable(); // stored file path
$table->string('alt')->nullable(); // alt attribute
$table->string('caption')->nullable(); // short caption
$table->text('description')->nullable();
$table->enum("type", ["public", "private"])->default("public");
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('files');
}
};
2. Routes
These are the routes I used to upload, display and delete files.
// routes/web.php
Route::post("/admin/files/delete", [FileController::class, "destroy"]);
Route::post("/admin/files/upload", [FileController::class, "upload"]);
Route::any("/admin/files", [FileController::class, "index"]);
3. Controller
This is my FileController that handles the file upload, view and delete functionality.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Storage;
use Validator;
class FileController extends Controller
{
public function destroy()
{
$validator = Validator::make(request()->all(), [
"id" => "required"
]);
if ($validator->fails())
{
return response()->json([
"status" => "error",
"message" => $validator->errors()->first()
]);
}
$id = request()->id ?? 0;
$media = DB::table('files')->where('id', $id)->first();
if (!$media)
{
return response()->json([
"status" => "error",
"message" => "File not found."
]);
}
if ($media->file_path && Storage::exists($media->type . "/" . $media->file_path))
{
Storage::delete($media->type . "/" . $media->file_path);
}
DB::table('files')->where('id', $id)->delete();
return response()->json([
"status" => "success",
"message" => "File has been deleted."
]);
}
public function upload()
{
$validator = Validator::make(request()->all(), [
"file" => "required",
"type" => "required"
]);
if ($validator->fails())
{
return response()->json([
"status" => "error",
"message" => $validator->errors()->first()
]);
}
$type = request()->type ?? "";
$file = request()->file("file");
if (!in_array($type, ["public", "private"]))
{
return response()->json([
"status" => "error",
"message" => "In-valid type '" . $type . "'."
]);
}
$data = [
'name' => request()->name ?? "",
'file_path' => "",
'alt' => request()->alt ?? "",
'caption' => request()->caption ?? "",
'description' => request()->description ?? "",
'created_at' => now()->utc(),
'updated_at' => now()->utc()
];
$file_path = "";
if ($file)
{
$file_path = "files/" . uniqid() . "." . $file->getClientOriginalExtension();
$file->storeAs("/" . $type, $file_path);
chmod(storage_path("app/" . $type . "/files"), 0755);
$data["file_path"] = $file_path;
}
$id = DB::table('files')->insertGetId($data);
return response()->json([
"status" => "success",
"message" => "File has been uploaded.",
"id" => $id,
"file_path" => url("/storage/" . $file_path)
]);
}
public function index()
{
if (request()->isMethod("post"))
{
set_timezone();
$files = DB::table('files')
->where("type", "=", "public")
->orderByDesc('id')
->paginate();
$files_arr = [];
foreach ($files as $file)
{
$obj = [
"id" => $file->id ?? 0,
"name" => $file->name ?? "",
"file_path" => $file->file_path ?? "",
"alt" => $file->alt ?? "",
"caption" => $file->caption ?? "",
"description" => $file->description ?? "",
"created_at" => date("d F, Y h:i:s a", strtotime($file->created_at . " UTC"))
];
if ($obj["file_path"] && Storage::exists("public/" . $obj["file_path"]))
{
$obj["file_path"] = url("/storage/" . $obj["file_path"]);
}
array_push($files_arr, (object) $obj);
}
return response()->json([
"status" => "success",
"message" => "Data has been fetched.",
"files" => $files_arr
]);
}
$files = DB::table('files')->orderByDesc('id')->paginate();
return view("admin/files/index", [
"files" => $files
]);
}
}
Do let me know if you face any problem in this.