From e86010bb75a3d4023a76335c8012a67dd1f1e695 Mon Sep 17 00:00:00 2001 From: GhassanYusuf Date: Sun, 25 Jan 2026 01:42:27 +0300 Subject: [PATCH] Initial release of Laravel Cropper package --- README.md | 0 composer.json | 22 +++ src/CropperServiceProvider.php | 42 +++++ src/Http/Controllers/ImageController.php | 43 +++++ .../views/components/widget.blade.php | 153 ++++++++++++++++++ 5 files changed, 260 insertions(+) create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/CropperServiceProvider.php create mode 100644 src/Http/Controllers/ImageController.php create mode 100644 src/resources/views/components/widget.blade.php diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..c237f52 --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "takeone/cropper", + "description": "Reusable Laravel image cropper using Cropme", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "Takeone\\Cropper\\": "src/" + } + }, + "extra": { + "laravel": { + "providers": [ + "Takeone\\Cropper\\CropperServiceProvider" + ] + } + }, + "require": { + "php": "^8.1", + "illuminate/support": "^10.0|^11.0|^12.0" + } +} diff --git a/src/CropperServiceProvider.php b/src/CropperServiceProvider.php new file mode 100644 index 0000000..ce11ba4 --- /dev/null +++ b/src/CropperServiceProvider.php @@ -0,0 +1,42 @@ +loadViewsFrom(__DIR__.'/resources/views', 'takeone'); + + // 2. Register Blade Component Alias + Blade::component('takeone::components.widget', 'takeone-cropper'); + + // 3. Register Routes Automatically + $this->registerRoutes(); + + // 4. Allow publishing views if user wants to customize + $this->publishes([ + __DIR__.'/resources/views' => resource_path('views/vendor/takeone'), + ], 'takeone-cropper-views'); + } + + protected function registerRoutes() + { + Route::group([ + 'middleware' => ['web'], + ], function () { + // We use the full absolute namespace here to avoid any "not found" errors + Route::post('/image-upload', [\takeone\cropper\Http\Controllers\ImageController::class, 'upload'])->name('image.upload'); + }); + } + + public function register() + { + // + } +} diff --git a/src/Http/Controllers/ImageController.php b/src/Http/Controllers/ImageController.php new file mode 100644 index 0000000..a6004dc --- /dev/null +++ b/src/Http/Controllers/ImageController.php @@ -0,0 +1,43 @@ +validate([ + 'image' => 'required', + 'folder' => 'required|string', + 'filename' => 'required|string', + ]); + + try { + $imageData = $request->image; + $imageParts = explode(";base64,", $imageData); + $imageTypeAux = explode("image/", $imageParts[0]); + $extension = $imageTypeAux[1]; + $imageBinary = base64_decode($imageParts[1]); + + $folder = trim($request->folder, '/'); + $fileName = $request->filename . '.' . $extension; + $fullPath = $folder . '/' . $fileName; + + // Store in the public disk (storage/app/public) + Storage::disk('public')->put($fullPath, $imageBinary); + + return response()->json([ + 'success' => true, + 'path' => $fullPath, + 'url' => asset('storage/' . $fullPath) + ]); + } catch (\Exception $e) { + return response()->json(['success' => false, 'message' => $e->getMessage()], 500); + } + } +} diff --git a/src/resources/views/components/widget.blade.php b/src/resources/views/components/widget.blade.php new file mode 100644 index 0000000..24cb13a --- /dev/null +++ b/src/resources/views/components/widget.blade.php @@ -0,0 +1,153 @@ +@php + $id = $attributes->get('id'); + $width = $attributes->get('width', 300); + $height = $attributes->get('height', 300); + $shape = $attributes->get('shape', 'circle'); + $folder = $attributes->get('folder', 'uploads'); + $filename = $attributes->get('filename', 'cropped_' . time()); +@endphp + +@once + + + + +@endonce + + + +@push('modals') + + + +@endpush