Add WooCommerce-style featured image and product gallery flow.
Deploy Ladill Woo Manager / deploy (push) Successful in 24s

Sync full image sets through the plugin, with upload/URL support in the product editor and thumbnails in the list.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-07 00:27:11 +00:00
co-authored by Cursor
parent e3ef23218f
commit 085645fd0f
10 changed files with 434 additions and 67 deletions
@@ -7,6 +7,7 @@ use App\Models\WooProduct;
use App\Models\WooStore;
use App\Services\Woo\CatalogSyncService;
use App\Services\Woo\CatalogWriteService;
use App\Services\Woo\ProductMediaService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
@@ -17,6 +18,7 @@ class ProductController extends Controller
public function __construct(
private CatalogWriteService $write,
private CatalogSyncService $sync,
private ProductMediaService $media,
) {}
public function index(Request $request): View
@@ -64,6 +66,7 @@ class ProductController extends Controller
{
$validated = $this->validateProduct($request);
$store = $this->authorizedStore($request, (int) $validated['woo_store_id']);
$validated['images'] = $this->media->buildImagesFromRequest($request, $store);
$this->write->createProduct($store, $validated);
@@ -90,6 +93,7 @@ class ProductController extends Controller
abort_if($product->store?->user_id !== $request->user()->id, 403);
$validated = $this->validateProduct($request, $product);
$validated['images'] = $this->media->buildImagesFromRequest($request, $product->store);
$this->write->updateProduct($product, $validated);
return redirect()->route('woo.products.index', ['store' => $product->woo_store_id])
@@ -129,6 +133,14 @@ class ProductController extends Controller
'description' => ['nullable', 'string', 'max:20000'],
'category_external_ids' => ['nullable', 'array'],
'category_external_ids.*' => ['integer', 'min:1'],
'product_images' => ['nullable', 'string'],
'featured_image_upload' => ['nullable', 'image', 'max:10240'],
'featured_image_src' => ['nullable', 'url', 'max:2000'],
'featured_image_alt' => ['nullable', 'string', 'max:255'],
'gallery_uploads' => ['nullable', 'array'],
'gallery_uploads.*' => ['image', 'max:10240'],
'gallery_image_srcs' => ['nullable', 'array'],
'gallery_image_srcs.*' => ['url', 'max:2000'],
]);
}