feat: Add MinIO storage support and update image URLs
All checks were successful
Deploy Production (merchbay.com) / deploy (push) Successful in 2m54s

- Implemented MinIO storage driver in AppServiceProvider for S3-compatible storage.
- Added helper functions to generate MinIO URLs for files and images.
- Updated filesystem configuration to include MinIO settings.
- Modified site configuration to include MinIO URL.
- Enhanced Docker Compose configuration for local development with MinIO.
- Updated various Blade templates to use MinIO URLs for images instead of local paths.
- Ensured all image references in views are now pointing to MinIO storage.
This commit is contained in:
Frank John Begornia
2026-05-13 00:25:23 +08:00
parent 6c97e60805
commit ad8d8d7564
28 changed files with 229 additions and 76 deletions

View File

@@ -3,6 +3,7 @@
namespace App\Exceptions;
use Exception;
use Throwable;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
@@ -23,11 +24,16 @@ class Handler extends ExceptionHandler
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @param \Throwable $e
* @return void
*/
public function report(Exception $e)
public function report(Throwable $e)
{
// Laravel 5.0 parent expects an Exception; wrap Error instances so
// PHP 7+ fatal errors (TypeError, ParseError, etc.) are handled safely.
if (!$e instanceof Exception) {
$e = new \RuntimeException($e->getMessage(), $e->getCode());
}
return parent::report($e);
}
@@ -43,11 +49,13 @@ class Handler extends ExceptionHandler
// return parent::render($request, $e);
// }
public function render($request, Exception $e)
public function render($request, Throwable $e)
{
if ($e instanceof MethodNotAllowedHttpException) {
abort(404);
}
return parent::render($request, $e);
// Wrap non-Exception Throwables for Laravel 5.0 parent compatibility.
$exception = $e instanceof Exception ? $e : new \RuntimeException($e->getMessage(), $e->getCode());
return parent::render($request, $exception);
}
}

View File

@@ -765,8 +765,7 @@ class UserController extends Controller
$u = $UserModel->insertNewProductThumbnails($thumbs);
// var_dump($thumbs);
Storage::disk('sftp')->put($thumbnail, fopen($request->file('imgupload')[$i], 'r+')); //live
//Storage::disk('localdir')->put($thumbnail, fopen($request->file('imgupload')[$i], 'r+'));
Storage::disk('minio_crewsportswear')->put('images/' . $thumbnail, fopen($request->file('imgupload')[$i], 'r+'));
// var_dump($s);
}
@@ -938,8 +937,7 @@ class UserController extends Controller
);
$u = $UserModel->insertNewProductThumbnails($thumbs);
Storage::disk('sftp')->put($thumbnail, fopen($request->file('upload_images')[$i], 'r+')); //live
//Storage::disk('localdir')->put($thumbnail, fopen($request->file('upload_images')[$i], 'r+'));
Storage::disk('minio_crewsportswear')->put('images/' . $thumbnail, fopen($request->file('upload_images')[$i], 'r+'));
}
@@ -961,6 +959,8 @@ class UserController extends Controller
unlink($storagePath . $file);
}
Storage::disk('minio_crewsportswear')->delete('images/' . $file);
$i = $UserModel->deleteImageThumb('Id', $id);
return response()->json(array(

View File

@@ -4,6 +4,8 @@ use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use League\Flysystem\Sftp\SftpAdapter;
use League\Flysystem\AwsS3v3\AwsS3Adapter as AwsS3v3Adapter;
use Aws\S3\S3Client;
use Illuminate\Support\Facades\Blade;
class AppServiceProvider extends ServiceProvider {
@@ -27,6 +29,21 @@ class AppServiceProvider extends ServiceProvider {
Storage::extend('sftp', function ($app, $config) {
return new Filesystem(new SftpAdapter($config));
});
Storage::extend('minio', function ($app, $config) {
$client = new S3Client([
'credentials' => [
'key' => $config['key'],
'secret' => $config['secret'],
],
'region' => $config['region'],
'version' => 'latest',
'endpoint' => $config['endpoint'],
'use_path_style_endpoint' => filter_var($config['use_path_style_endpoint'] ?? true, FILTER_VALIDATE_BOOLEAN),
]);
$adapter = new AwsS3v3Adapter($client, $config['bucket']);
return new Filesystem($adapter);
});
}
/**

33
app/helpers.php Normal file
View File

@@ -0,0 +1,33 @@
<?php
if (!function_exists('minio_url')) {
/**
* Generate MinIO URL for a file.
*
* @param string $path File path relative to bucket
* @return string Full MinIO URL
*/
function minio_url($path)
{
$bucket = env('MINIO_BUCKET', 'merchbay');
$baseUrl = env('MINIO_URL', 'https://minio.crewsportswear.app');
// Remove leading slash if present
$path = ltrim($path, '/');
return $baseUrl . '/' . $bucket . '/' . $path;
}
}
if (!function_exists('minio_image_url')) {
/**
* Generate MinIO URL for an image in uploads/images/.
*
* @param string $filename Image filename
* @return string Full MinIO URL
*/
function minio_image_url($filename)
{
return minio_url('uploads/images/' . $filename);
}
}