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:
2026-02-27 18:18:12 +01:00
parent d51353e5cc
commit 571f0a990f

View File

@@ -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'),