diff --git a/app/Http/Controllers/Admin/CourseController.php b/app/Http/Controllers/Admin/CourseController.php index 824cd17..178de2d 100755 --- a/app/Http/Controllers/Admin/CourseController.php +++ b/app/Http/Controllers/Admin/CourseController.php @@ -9,6 +9,8 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; +use Intervention\Image\ImageManager; +use Intervention\Image\Drivers\Gd\Driver; class CourseController extends Controller { @@ -17,6 +19,30 @@ class CourseController extends Controller $this->middleware('auth'); } + private function generateThumbnail($imagePath, $width = 400, $height = 300) + { + $manager = new ImageManager(new Driver()); + $image = $manager->read($imagePath); + + // Пропорциональное уменьшение с crop по центру + $image->cover($width, $height, 'center'); + + // Сохраняем как _thumb версию + $thumbPath = str_replace('.', '_thumb.', $imagePath); + $image->save(storage_path('app/public/' . $thumbPath)); + + return str_replace('.', '_thumb.', $imagePath); + } + + private function deleteThumbnails($path) + { + if (!$path) return; + + $thumbPath = str_replace('.', '_thumb.', $path); + Storage::disk('public')->delete($thumbPath); + Storage::disk('public')->delete($path); + } + public function index(Request $request) { Gate::authorize('viewAny', Course::class); @@ -81,7 +107,8 @@ class CourseController extends Controller $validated['has_certificate'] = $request->boolean('has_certificate'); if ($request->hasFile('thumbnail')) { - $validated['thumbnail'] = $request->file('thumbnail')->store('courses/thumbnails', 'public'); + $path = $request->file('thumbnail')->store('courses/thumbnails', 'public'); + $validated['thumbnail'] = $this->generateThumbnail($path, 400, 300); } $course = Course::create($validated); @@ -134,8 +161,9 @@ class CourseController extends Controller $validated['has_certificate'] = $request->boolean('has_certificate'); if ($request->hasFile('thumbnail')) { - if ($course->thumbnail) Storage::disk('public')->delete($course->thumbnail); - $validated['thumbnail'] = $request->file('thumbnail')->store('courses/thumbnails', 'public'); + if ($course->thumbnail) $this->deleteThumbnails($course->thumbnail); + $path = $request->file('thumbnail')->store('courses/thumbnails', 'public'); + $validated['thumbnail'] = $this->generateThumbnail($path, 400, 300); } $course->update($validated); @@ -147,7 +175,7 @@ class CourseController extends Controller { Gate::authorize('delete', $course); - if ($course->thumbnail) Storage::disk('public')->delete($course->thumbnail); + $this->deleteThumbnails($course->thumbnail); $course->delete(); diff --git a/composer.json b/composer.json index 46b9787..422c9e5 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "php": "^8.3", "guzzlehttp/guzzle": "^7.9", + "intervention/image": "^3.11", "laravel/framework": "dev-master as 13.0", "laravel/sanctum": "^4.0", "laravel/tinker": "^2.10", diff --git a/composer.lock b/composer.lock index e8b0c79..25be1d4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "54cdb3ddf3312af9d237737159ea9d71", + "content-hash": "5e9268b759e635964ff26f5e09bc95bc", "packages": [ { "name": "brick/math", @@ -1002,6 +1002,142 @@ ], "time": "2025-02-03T10:55:03+00:00" }, + { + "name": "intervention/gif", + "version": "4.2.1", + "source": { + "type": "git", + "url": "https://github.com/Intervention/gif.git", + "reference": "6addac2c68b4bc0e37d0d3ccedda57eb84729c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/gif/zipball/6addac2c68b4bc0e37d0d3ccedda57eb84729c49", + "reference": "6addac2c68b4bc0e37d0d3ccedda57eb84729c49", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Gif\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Native PHP GIF Encoder/Decoder", + "homepage": "https://github.com/intervention/gif", + "keywords": [ + "animation", + "gd", + "gif", + "image" + ], + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-01-05T10:52:39+00:00" + }, + { + "name": "intervention/image", + "version": "3.11.1", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "0f87254688e480fbb521e2a1ac6c11c784ca41af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/0f87254688e480fbb521e2a1ac6c11c784ca41af", + "reference": "0f87254688e480fbb521e2a1ac6c11c784ca41af", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "intervention/gif": "^4.2", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "ext-exif": "Recommended to be able to read EXIF data properly." + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "PHP image manipulation", + "homepage": "https://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "resize", + "thumbnail", + "watermark" + ], + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-02-01T07:28:26+00:00" + }, { "name": "laravel/framework", "version": "dev-master", diff --git a/resources/views/admin/courses/index.blade.php b/resources/views/admin/courses/index.blade.php index 6d342d9..6cd9ed8 100644 --- a/resources/views/admin/courses/index.blade.php +++ b/resources/views/admin/courses/index.blade.php @@ -43,7 +43,7 @@