feat: load and save per-integration content in product edit/update
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,7 +35,7 @@ final class ProductsController
|
||||
'search' => trim((string) $request->input('search', '')),
|
||||
'status' => (string) $request->input('status', ''),
|
||||
'type' => (string) $request->input('type', ''),
|
||||
'sort' => (string) $request->input('sort', 'id'),
|
||||
'sort' => (string) $request->input('sort', 'created_at'),
|
||||
'sort_dir' => (string) $request->input('sort_dir', 'DESC'),
|
||||
'page' => max(1, (int) $request->input('page', 1)),
|
||||
'per_page' => max(1, min(100, (int) $request->input('per_page', 20))),
|
||||
@@ -109,43 +109,6 @@ final class ProductsController
|
||||
'variant_parent' => $this->translator->get('products.type.variant_parent'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'sort',
|
||||
'label' => $this->translator->get('products.filters.sort'),
|
||||
'type' => 'select',
|
||||
'value' => $filtersValues['sort'],
|
||||
'options' => [
|
||||
'id' => 'ID',
|
||||
'name' => $this->translator->get('products.fields.name'),
|
||||
'sku' => 'SKU',
|
||||
'ean' => 'EAN',
|
||||
'price_brutto' => $this->translator->get('products.fields.price_brutto'),
|
||||
'quantity' => $this->translator->get('products.fields.quantity'),
|
||||
'status' => $this->translator->get('products.fields.status'),
|
||||
'updated_at' => $this->translator->get('products.fields.updated_at'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'sort_dir',
|
||||
'label' => $this->translator->get('products.filters.direction'),
|
||||
'type' => 'select',
|
||||
'value' => $filtersValues['sort_dir'],
|
||||
'options' => [
|
||||
'DESC' => 'DESC',
|
||||
'ASC' => 'ASC',
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'per_page',
|
||||
'label' => $this->translator->get('products.filters.per_page'),
|
||||
'type' => 'select',
|
||||
'value' => (string) $filtersValues['per_page'],
|
||||
'options' => [
|
||||
'20' => '20',
|
||||
'50' => '50',
|
||||
'100' => '100',
|
||||
],
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
['key' => 'id', 'label' => 'ID', 'sortable' => true, 'sort_key' => 'id'],
|
||||
@@ -157,6 +120,7 @@ final class ProductsController
|
||||
['key' => 'quantity', 'label' => $this->translator->get('products.fields.quantity'), 'sortable' => true, 'sort_key' => 'quantity'],
|
||||
['key' => 'status_label', 'label' => $this->translator->get('products.fields.status'), 'raw' => true, 'sortable' => true, 'sort_key' => 'status'],
|
||||
['key' => 'updated_at', 'label' => $this->translator->get('products.fields.updated_at'), 'sortable' => true, 'sort_key' => 'updated_at'],
|
||||
['key' => 'created_at', 'label' => $this->translator->get('products.fields.created_at'), 'sortable' => true, 'sort_key' => 'created_at'],
|
||||
],
|
||||
'selectable' => true,
|
||||
'select_name' => 'export_product_ids[]',
|
||||
@@ -169,7 +133,7 @@ final class ProductsController
|
||||
'total' => (int) ($result['total'] ?? 0),
|
||||
'per_page' => (int) ($result['per_page'] ?? 20),
|
||||
],
|
||||
'per_page_options' => [20, 50, 100],
|
||||
'per_page_options' => [10, 20, 50, 100],
|
||||
'empty_message' => $this->translator->get('products.empty'),
|
||||
'show_actions' => true,
|
||||
'actions_label' => $this->translator->get('products.fields.actions'),
|
||||
@@ -236,6 +200,15 @@ final class ProductsController
|
||||
$form = $this->mergeOldWithProduct($product);
|
||||
$productImages = $this->withPublicImageUrls($this->products->findImagesByProductId($id));
|
||||
|
||||
$activeIntegrations = $this->integrations->listByType('shoppro');
|
||||
$integrationTranslations = $this->products->findIntegrationTranslations($id);
|
||||
|
||||
// Index integration translations by integration_id for easy lookup in view
|
||||
$integrationTranslationsMap = [];
|
||||
foreach ($integrationTranslations as $it) {
|
||||
$integrationTranslationsMap[(int) $it['integration_id']] = $it;
|
||||
}
|
||||
|
||||
$html = $this->template->render('products/edit', [
|
||||
'title' => $this->translator->get('products.edit.title', ['id' => (string) $id]),
|
||||
'activeMenu' => 'products',
|
||||
@@ -246,6 +219,8 @@ final class ProductsController
|
||||
'form' => $form,
|
||||
'productImages' => $productImages,
|
||||
'errors' => (array) Flash::get('products_form_errors', []),
|
||||
'activeIntegrations' => $activeIntegrations,
|
||||
'integrationTranslationsMap' => $integrationTranslationsMap,
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
@@ -480,6 +455,24 @@ final class ProductsController
|
||||
}
|
||||
}
|
||||
|
||||
// Save per-integration content overrides
|
||||
$integrationContent = $request->input('integration_content', []);
|
||||
if (is_array($integrationContent)) {
|
||||
foreach ($integrationContent as $rawIntegrationId => $content) {
|
||||
$integrationId = (int) $rawIntegrationId;
|
||||
if ($integrationId <= 0 || !is_array($content)) {
|
||||
continue;
|
||||
}
|
||||
$this->products->upsertIntegrationTranslation(
|
||||
$id,
|
||||
$integrationId,
|
||||
isset($content['name']) ? trim((string) $content['name']) : null,
|
||||
isset($content['short_description']) ? trim((string) $content['short_description']) : null,
|
||||
isset($content['description']) ? trim((string) $content['description']) : null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Flash::set('products_form_old', []);
|
||||
Flash::set('products_success', $this->translator->get('products.flash.updated'));
|
||||
|
||||
@@ -795,6 +788,7 @@ final class ProductsController
|
||||
)
|
||||
),
|
||||
'updated_at' => (string) ($row['updated_at'] ?? ''),
|
||||
'created_at' => (string) ($row['created_at'] ?? ''),
|
||||
'_actions' => [
|
||||
[
|
||||
'label' => $this->translator->get('products.actions.preview'),
|
||||
|
||||
Reference in New Issue
Block a user