From 4b2a9130cda88a882d59d9ea640776ecd454db48 Mon Sep 17 00:00:00 2001 From: iFannJR Date: Mon, 1 Jun 2026 00:54:18 +0700 Subject: [PATCH] ubah image db ke blob --- .../Controllers/Admin/ProductController.php | 19 +- app/Models/Product.php | 9 +- composer.json | 1 + composer.lock | 205 +++++++++++++++++- ...image_column_to_blob_in_products_table.php | 23 ++ resources/views/admin/products/edit.blade.php | 4 +- .../views/admin/products/index.blade.php | 4 +- resources/views/user/cart.blade.php | 4 +- .../user/recommendation-result.blade.php | 4 +- resources/views/user/shop.blade.php | 2 +- resources/views/welcome.blade.php | 2 +- 11 files changed, 257 insertions(+), 20 deletions(-) create mode 100644 database/migrations/2026_05_31_232947_change_image_column_to_blob_in_products_table.php diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php index 535a0ce..fa8a0ff 100644 --- a/app/Http/Controllers/Admin/ProductController.php +++ b/app/Http/Controllers/Admin/ProductController.php @@ -16,7 +16,7 @@ class ProductController extends Controller public function index(Request $request) { $products = Product::with('criterias') - ->when($request->search, fn ($q, $v) => $q->where('name', 'like', "%{$v}%")) + ->when($request->search, fn($q, $v) => $q->where('name', 'like', "%{$v}%")) ->latest() ->paginate(10) ->withQueryString(); @@ -33,8 +33,11 @@ public function create() public function store(StoreProductRequest $request) { $data = $request->validated(); - if ($request->hasFile('image')) { - $data['image'] = $request->file('image')->store('products', 'public'); + $imgFile = $request->file('image'); + if ($imgFile) { + $binaryData = file_get_contents($imgFile->getRealPath()); + $data['image'] = $binaryData; + $data['image_type'] = $imgFile->extension(); } $criteriaValuesById = $data['criteria_values'] ?? []; @@ -67,11 +70,11 @@ public function edit(Product $product) public function update(UpdateProductRequest $request, Product $product) { $data = $request->validated(); - if ($request->hasFile('image')) { - if ($product->image) { - Storage::disk('public')->delete($product->image); - } - $data['image'] = $request->file('image')->store('products', 'public'); + $imgFile = $request->file('image'); + if ($imgFile) { + $binaryData = file_get_contents($imgFile->getRealPath()); + $data['image'] = $binaryData; + $data['image_type'] = $imgFile->extension(); } $criteriaValuesById = $data['criteria_values'] ?? []; diff --git a/app/Models/Product.php b/app/Models/Product.php index 4058fa8..90c4cdc 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -11,7 +11,14 @@ class Product extends Model use HasFactory; protected $fillable = [ - 'name', 'description', 'price', 'stock', 'age_range', 'category', 'image', + 'name', + 'description', + 'price', + 'stock', + 'age_range', + 'category', + 'image', + 'image_type' ]; protected $casts = [ diff --git a/composer.json b/composer.json index 52a3a8a..5b06b43 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "license": "MIT", "require": { "php": "^8.2", + "doctrine/dbal": "^4.4", "laravel/framework": "^12.0", "laravel/tinker": "^2.10.1" }, diff --git a/composer.lock b/composer.lock index ba15390..e36d59a 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": "c514d8f7b9fc5970bdd94287905ef584", + "content-hash": "620aac251098636f5fe91599b3e050d2", "packages": [ { "name": "brick/math", @@ -210,6 +210,160 @@ }, "time": "2024-07-08T12:26:09+00:00" }, + { + "name": "doctrine/dbal", + "version": "4.4.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "61e730f1658814821a85f2402c945f3883407dec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/61e730f1658814821a85f2402c945f3883407dec", + "reference": "61e730f1658814821a85f2402c945f3883407dec", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1.5", + "php": "^8.2", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "14.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.2", + "phpstan/phpstan": "2.1.30", + "phpstan/phpstan-phpunit": "2.0.7", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "11.5.50", + "slevomat/coding-standard": "8.27.1", + "squizlabs/php_codesniffer": "4.0.1", + "symfony/cache": "^6.3.8|^7.0|^8.0", + "symfony/console": "^5.4|^6.3|^7.0|^8.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/4.4.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2026-03-20T08:52:12+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=14" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" + }, + "time": "2026-02-07T07:09:04+00:00" + }, { "name": "doctrine/inflector", "version": "2.1.0", @@ -2607,6 +2761,55 @@ ], "time": "2025-12-27T19:41:33+00:00" }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/database/migrations/2026_05_31_232947_change_image_column_to_blob_in_products_table.php b/database/migrations/2026_05_31_232947_change_image_column_to_blob_in_products_table.php new file mode 100644 index 0000000..4efd24a --- /dev/null +++ b/database/migrations/2026_05_31_232947_change_image_column_to_blob_in_products_table.php @@ -0,0 +1,23 @@ +enum('image_type', ['jpg', 'png', 'webp', 'gif'])->nullable()->after('image'); + }); + } + + public function down(): void + { + Schema::table('products', function (Blueprint $table) { + $table->string('image', 255)->nullable()->change(); + }); + } +}; \ No newline at end of file diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php index fbbca07..5ec45ee 100644 --- a/resources/views/admin/products/edit.blade.php +++ b/resources/views/admin/products/edit.blade.php @@ -25,8 +25,8 @@
- @if($product->image) -

Saat ini:

+ @if($product->image_type) +

Saat ini:

@endif
diff --git a/resources/views/admin/products/index.blade.php b/resources/views/admin/products/index.blade.php index d0b71e2..4617047 100644 --- a/resources/views/admin/products/index.blade.php +++ b/resources/views/admin/products/index.blade.php @@ -34,8 +34,8 @@ @forelse($products as $p) - @if($p->image) - + @if($p->image_type) + @else 🧸 @endif diff --git a/resources/views/user/cart.blade.php b/resources/views/user/cart.blade.php index 1228a7b..469f53b 100644 --- a/resources/views/user/cart.blade.php +++ b/resources/views/user/cart.blade.php @@ -33,8 +33,8 @@
- @if($item->product->image) - + @if($item->product->image_type) + @else
🧸
@endif diff --git a/resources/views/user/recommendation-result.blade.php b/resources/views/user/recommendation-result.blade.php index e912582..8259fe4 100644 --- a/resources/views/user/recommendation-result.blade.php +++ b/resources/views/user/recommendation-result.blade.php @@ -34,8 +34,8 @@
- @if($rec['product']->image) - {{ $rec['product']->name }} + @if($rec['product']->image_type) + {{ $rec['product']->name }} @else 🧸 @endif diff --git a/resources/views/user/shop.blade.php b/resources/views/user/shop.blade.php index c2da6d1..1acc078 100644 --- a/resources/views/user/shop.blade.php +++ b/resources/views/user/shop.blade.php @@ -66,7 +66,7 @@ :price="$product->price" :age-range="$product->age_range" :stock="$product->stock" - :image="$product->image ? Storage::url($product->image) : null" + :image="$product->image_type ? 'data:image/' . $product->image_type . ';base64,' . base64_encode($product->image) : null" >
@csrf diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index c501cf2..1b6ca4b 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -48,7 +48,7 @@ :price="$product->price" :age-range="$product->age_range" :stock="$product->stock" - :image="$product->image ? asset('storage/' . $product->image) : null" + :image="$product->image_type ? 'data:image/' . $product->image_type . ';base64,' . base64_encode($product->image) : null" > Lihat