<?php
declare(strict_types=1);
namespace SwagHoggi\Storefront\Controller;
use RuntimeException;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItemFactoryRegistry;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Content\Media\MediaEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\AndFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use SwagHoggi\Core\Content\Hoggi\Configurator\ConfiguratorEntity;
use SwagHoggi\Core\Content\Hoggi\Configurator\ConfiguratorProductCustomFieldEntity;
use SwagHoggi\Core\Content\Hoggi\Configurator\SavedConfigurationEntity;
use SwagHoggi\Service\Checkout\Cart\HoggiConfiguratorCartItemHandler;
use SwagHoggi\Storefront\Page\HoggiConfigurator\HoggiConfiguratorPageLoader;
use SwagHoggi\Storefront\Page\SavedConfigurationListing\SavedConfigurationListingPageLoader;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route(defaults={"_routeScope"={"storefront"}})
*/
class HoggiConfiguratorController extends StorefrontController
{
private EntityRepository $configuratorRepository;
private EntityRepository $productRepository;
private EntityRepository $savedConfigurationRepository;
private LineItemFactoryRegistry $factory;
private CartService $cartService;
private HoggiConfiguratorPageLoader $configuratorPageLoader;
private SavedConfigurationListingPageLoader $savedConfiguratorListingPageLoader;
private EntityRepository $configuratorProductCustomFieldsRepository;
/**
* @param EntityRepository $configuratorRepository
* @param EntityRepository $productRepository
* @param LineItemFactoryRegistry $factory
* @param CartService $cartService
* @param HoggiConfiguratorPageLoader $configuratorPageLoader
*/
public function __construct(
EntityRepository $configuratorRepository,
EntityRepository $productRepository,
EntityRepository $savedConfigurationRepository,
LineItemFactoryRegistry $factory,
CartService $cartService,
HoggiConfiguratorPageLoader $configuratorPageLoader,
SavedConfigurationListingPageLoader $savedConfiguratorListingPageLoader,
EntityRepository $configuratorProductCustomFieldsRepository
) {
$this->configuratorRepository = $configuratorRepository;
$this->productRepository = $productRepository;
$this->savedConfigurationRepository = $savedConfigurationRepository;
$this->factory = $factory;
$this->cartService = $cartService;
$this->configuratorPageLoader = $configuratorPageLoader;
$this->savedConfiguratorListingPageLoader = $savedConfiguratorListingPageLoader;
$this->configuratorProductCustomFieldsRepository = $configuratorProductCustomFieldsRepository;
}
/**
* @param Request $request
* @param Cart $cart Current cart
* @param SalesChannelContext $context Current context
* @return Response
* @Route("/hoggi-configurator/addcart", name="frontend.hoggi-configurator.add-cart", methods={"POST"}, defaults={"csrf_protected"=false, "XmlHttpRequest"=true})
*/
public function addCart(Request $request, Cart $cart, SalesChannelContext $context): Response
{
$productsIds = $request->request->get("products") ?: [];
$comment = $request->request->get("comment") ?? "";
$configurator = $request->request->get("configurator") ?: [];
$configuratorId = $request->request->get("configuratorId") ?: null;
$savedConfigurationName = $request->request->get("savedConfigurationName") ?: null;
$savedConfigurationId = $request->request->get("savedConfigurationId") ?: null;
// clear cart
/*
foreach ($cart->getLineItems()->filterFlatByType(HoggiConfiguratorCartItemHandler::TYPE) as $lineItem) {
$this->factory->update($cart, [
"id" => $lineItem->getId(),
"removable" => true
], $context);
$this->cartService->remove($cart, $lineItem->getId(), $context);
}
*/
/** @var array $products */
$products = array_map(function ($productId) use ($context, $configuratorId) {
/** @var ProductEntity $product */
$product = $this->productRepository->search(new Criteria([$productId]), $context->getContext())->first();
if ($product === null) {
throw new RuntimeException("Product id '$productId' not found!");
}
$data = $product->getCustomFields();
if (empty($data) || (is_array($data) && count($data) <= 0)) {
$criteria = new Criteria();
$criteria->addFilter(new AndFilter([
new EqualsFilter("configurator", $configuratorId),
new EqualsFilter("productNumber", $product->getProductNumber())
]
));
/** @var ConfiguratorProductCustomFieldEntity $configuratorProductCustomFields */
$configuratorProductCustomFields = $this->configuratorProductCustomFieldsRepository->search($criteria, $context->getContext())->first();
if ($configuratorProductCustomFields) {
$data = $configuratorProductCustomFields->getCustomFields();
$product->setCustomFields($data);
}
}
return [
"productId" => $productId,
"productNumber" => $product->getProductNumber(),
"outputOrder" => (int)($product->getCustomFields()['output_order'] ?? PHP_INT_MAX),
"smallHint" => $product->getCustomFields()['small_hint'] ?? null
];
}, $productsIds);
usort($products, function (array $a, array $b) {
// sort by output_order
if ($a["outputOrder"] < $b["outputOrder"]) {
return -1;
} elseif ($a["outputOrder"] > $b["outputOrder"]) {
return 1;
}
// sort by product number/sku
$skuCompare = strcmp($a["productNumber"], $b["productNumber"]);
if ($skuCompare !== 0) {
return $skuCompare;
}
// more maybe..?
return 0;
});
$cart->setCustomerComment($comment);
$this->cartService->recalculate($cart, $context);
$configuratorItem = $this->factory->create([
"type" => HoggiConfiguratorCartItemHandler::TYPE,
"savedConfigurationName" => $savedConfigurationName,
"savedConfigurationId" => $savedConfigurationId,
"referenceId" => $configuratorId,
"configurator" => $configurator,
"removable" => true
], $context);
// dump($configuratorItem); die;
// add products
foreach ($products as ["productId" => $productId, "outputOrder" => $outputOrder, "smallHint" => $smallHint]) {
// Create product line item
$lineItem = $this->factory->create([
'type' => LineItem::PRODUCT_LINE_ITEM_TYPE, // Results in 'product'
'referencedId' => $productId, // this is not a valid UUID, change this to your actual ID!
'quantity' => 1,
'payload' => ['type' => 'hoggi-configurator', 'output_order' => $outputOrder, 'small_hint' => $smallHint],
], $context);
// $this->cartService->add($cart, $lineItem, $context);
$configuratorItem->getChildren()->add($lineItem);
}
// Add the configurator itself to cart
$this->cartService->add($cart, $configuratorItem, $context);
// dump($cart->getLineItems()); die;
return new JsonResponse(true);
}
/**
* @Route("/hoggi-configurator/{id}/structure", name="frontend.hoggi-configurator.structure", methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function structure(string $id, SalesChannelContext $context): Response
{
$criteria = new Criteria();
$criteria->setLimit(1);
$criteria->setIds([$id]);
$criteria->addAssociation("products");
$criteria->addAssociation("products.cover.media");
/** @var ConfiguratorEntity $configurator */
$configurator = $this->configuratorRepository->search($criteria, $context->getContext())->first();
$layout = $configurator->getLayout();
$tabData = [];
foreach ($layout["tabs"] as $layoutTab) {
$type = $layoutTab["type"] ?? "product";
switch ($type) {
case "product":
$newTabData = $this->structureProductTab($configurator, $layoutTab, $context);
$tabData = array_merge($tabData, $newTabData);
break;
case "matrix_config":
$newTabData = $this->structureMatrixConfigTab($configurator, $layoutTab, $context);
$tabData = array_merge($tabData, $newTabData);
break;
}
}
$tabs = array_values($tabData);
foreach ($tabs as $tabIndex => $tab) {
$optionGroupsData = [];
foreach ($tab["sections"] as $section)
foreach ($section["products"] as $product) {{
$optionGroup = $product["optionGroup"];
if ($optionGroup === null) {
continue;
}
$optionGroupId = $optionGroup["id"];
if (!array_key_exists($optionGroupId, $optionGroupsData)) {
$optionGroupsData[$optionGroupId] = $optionGroup + [
"sectionCount" => 1
];
} else {
$optionGroupsData[$optionGroupId]["sectionCount"] += 1;
}
// only take first option group of section
break;
}
}
$tabs[$tabIndex]["optionGroups"] = array_values($optionGroupsData);
}
$data = [
"id" => $id,
"title" => $layout["title"] ?? null,
"theme" => $layout["theme"] ?? null,
"config" => $layout["config"] ?? [],
"tabs" => $tabs
];
return new JsonResponse($data);
}
private function structureProductTab(ConfiguratorEntity $configurator, array $layoutTab, SalesChannelContext $context): array
{
$tabData = [];
$sectionData = $this->structureSections($layoutTab["sections"] ?? []);
$tabId = $layoutTab["id"];
$tabData[$tabId] = [
"id" => $tabId,
"type" => "product",
"name" => $layoutTab["title"] ?? $tabId,
"sections" => $sectionData
];
$products = $configurator->getProducts();
/** @var ProductEntity $product */
foreach ($products as $product) {
$data = $product->getCustomFields();
if (empty($data) || (is_array($data) && count($data) <= 0)) {
$criteria = new Criteria();
$criteria->addFilter(new AndFilter([
new EqualsFilter("configurator", $configurator->getId()),
new EqualsFilter("productNumber", $product->getProductNumber())
]
));
/** @var ConfiguratorProductCustomFieldEntity $configuratorProductCustomFields */
$configuratorProductCustomFields = $this->configuratorProductCustomFieldsRepository->search($criteria, $context->getContext())->first();
if ($configuratorProductCustomFields) {
$data = $configuratorProductCustomFields->getCustomFields();
$product->setCustomFields($data);
}
}
$tabId = $data["configurator_tab"] ?? null;
$sectionId = $data["configurator_tab_section"] ?? $tabId;
if (!$tabId) {
continue;
}
if (!isset($tabData[$tabId]["sections"][$sectionId])) {
continue;
}
$currentSection = &$tabData[$tabId]["sections"][$sectionId];
$productData = $this->buildProductData($product, $currentSection["canHide"], $context);
$currentSection["products"][] = $productData;
}
foreach ($tabData as &$tab) {
$tab["sections"] = array_values($tab["sections"]);
foreach ($tab["sections"] as &$section) {
$this->orderProducts($section["products"]);
}
}
return $tabData;
}
private function structureSections(array $layoutSections): array {
$sectionData = [];
foreach ($layoutSections as $layoutSection) {
$sectionId = $layoutSection["id"];
$sectionData[$sectionId] = [
"id" => $sectionId,
"name" => $layoutSection["title"] ?? $sectionId,
"canHide" => $layoutSection["canHide"] ?? true,
"hideIncompatible" => $layoutSection["hideIncompatible"] ?? false,
"hideInSummary" => $layoutSection["hideInSummary"] ?? false,
"cover" => $layoutSection["cover"] ?? null,
"coverDirection" => $layoutSection["coverDirection"] ?? "left",
"hint" => $layoutSection["hint"] ?? null,
"products" => [],
"type" => $layoutSection["type"] ?? "product",
"options" => $layoutSection["options"] ?? null,
"contents" => $layoutSection["contents"] ?? [],
"contentVerticalAlignment" => $layoutSection["contentVerticalAlignment"] ?? "top"
];
}
return $sectionData;
}
private function orderProducts(array &$products) {
usort($products, function (array $productA, array $productB) {
return strcasecmp($productA["productNumber"], $productB["productNumber"]);
});
}
private function restExplode(string|array|null $value, bool $fixNumber = false): array
{
if (is_array($value)) {
return $value;
}
if (empty($value)) {
return [];
}
if ($fixNumber && is_string($value) && preg_match("/^\d+\.\d+$/", trim($value)) === 1) {
// Assume tha excel changed a 2 element list into a number and try to fix it
$value = str_replace(".", ",", $value);
}
return array_filter(array_map("trim", explode(",", $value)));
}
private function parsePreCondition(?string $preCondition): ?string {
if (empty($preCondition)) {
return null;
}
return preg_replace([
'/\s*\|\|\s*/',
'/\s*&&\s*/'
], [
' OR ',
' AND '
], $preCondition);
}
private function structureMatrixConfigTab(ConfiguratorEntity $configurator, array $layoutTab, SalesChannelContext $context): array {
$tabId = $layoutTab["id"];
$sectionData = isset($layoutTab["sections"]) ? $this->structureSections($layoutTab["sections"]) : [];
$products = $configurator->getProducts();
$productData = [];
/** @var ProductEntity $product */
foreach ($products as $product) {
$data = $product->getCustomFields();
if (empty($data) || (is_array($data) && count($data) <= 0)) {
$criteria = new Criteria();
$criteria->addFilter(new AndFilter([
new EqualsFilter("configurator", $configurator->getId()),
new EqualsFilter("productNumber", $product->getProductNumber())
]
));
/** @var ConfiguratorProductCustomFieldEntity $configuratorProductCustomFields */
$configuratorProductCustomFields = $this->configuratorProductCustomFieldsRepository->search($criteria, $context->getContext())->first();
if ($configuratorProductCustomFields) {
$data = $configuratorProductCustomFields->getCustomFields();
$product->setCustomFields($data);
}
}
$productTabId = $data["configurator_tab"] ?? null;
if ($productTabId === null || $productTabId !== $tabId) {
continue; // doesnt belong to tab, skip
}
$productData[] = $this->buildProductData($product, false, $context);
}
$this->orderProducts($productData);
$layoutFields = $layoutTab["config"]["fields"] ?? [];
$layoutMatrixType = $layoutTab["config"]["type"] ?? null;
$layoutMatrix = $layoutTab["config"]["matrix"] ?? [];
$fields = [];
foreach ($layoutFields as $layoutField) {
$field = [
"id" => $layoutField["id"],
"name" => $layoutField["title"],
"type" => $layoutField["type"],
"valueParent" => $layoutField["value_parent"] ?? null,
"filterField" => $layoutField["filter_field"] ?? null,
"requires" => $layoutField["requires"] ?? [],
"valueFormat" => $layoutField["value_format"] ?? null,
"values" => $layoutField["values"] ?? null,
"productGroup" => $layoutField["product_group"] ?? null,
"valueMeta" => $layoutField["value_meta"] ?? null,
];
if ($field["id"] === "seat_width") {
$seatDepthEntries = [];
foreach ($field["values"] as $value) {
$productNumber = $value["article_number"] ?? null;
if ($productNumber === null) {
continue;
}
$seatWidthProduct = $this->findProductInDataByProductNumber($productData, $productNumber);
if ($seatWidthProduct === null) {
continue;
}
$seatDepths = $seatWidthProduct["seatDepths"] ?? null;
if (empty($seatDepths)) {
continue;
}
$seatDepthEntries[$productNumber] = $seatDepths;
}
$field["seatDepths"] = $seatDepthEntries;
}
if ($layoutField["type"] === "seat-depth") {
$field["minValue"] = $layoutField["min_value"] ?? null;
$field["maxValue"] = $layoutField["max_value"] ?? null;
$field["extraCostProduct"] = $layoutField["extra_cost_article"] ?? null;
}
$fields[] = $field;
}
if ($sectionData) {
// remove string keys
$sectionData = array_values($sectionData);
}
$tabData = [
"id" => $tabId,
"name" => $layoutTab["title"] ?? $tabId,
"type" => "matrix_config",
"config" => [
"name" => $layoutTab["config"]["title"] ?? "",
"fields" => $fields,
"type" => $layoutMatrixType,
"matrix" => $layoutMatrix,
"cover" => $layoutTab["config"]["cover"] ?? null
],
"sections" => $sectionData,
"products" => $productData
];
return [$tabId => $tabData];
}
/**
* @param string|null $countPerGroupRaw
* @return array 0=>$countPerGroup, 1=>$optionGroup
*/
private function parseCountPerGroupAndOptionGroup(?string $countPerGroupRaw): array
{
if (empty($countPerGroupRaw)) {
return [null, null];
} else {
// Format is "id:name:countPerGroup" or "id:countPerGroup"
if (preg_match("~^([^:\n]+):(?:([^:\n]+):)?([^:\n]+)$~", $countPerGroupRaw, $optionGroupMatch) === 1) {
$optionGroup = [
"id" => $optionGroupMatch[1],
"name" => $optionGroupMatch[2] ?: $optionGroupMatch[1], // fallback to id
"countPerGroup" => $optionGroupMatch[3],
];
// "Turn off" section validation by using "0,N"
return [$optionGroupMatch[3], $optionGroup];
} else {
return [$countPerGroupRaw, null];
}
}
}
private function getThumbnail(SalesChannelContext $context, ?MediaEntity $media, int $targetHeight, int $targetWidth): ?string
{
if ($media == null) {
return null;
}
$bestMatch = null;
$minDistance = PHP_INT_MAX;
foreach ($media->getThumbnails() as $thumbnail) {
$distance = abs($thumbnail->getWidth() - $targetWidth) + abs($thumbnail->getHeight() - $targetHeight);
if ($distance < $minDistance) {
$minDistance = $distance;
$bestMatch = $thumbnail;
}
}
if ($bestMatch) {
return $bestMatch->getUrl();
} else {
return $media->getUrl();
}
}
function buildProductData (ProductEntity $product, bool $canHide, SalesChannelContext $context): array
{
$data = $product->getCustomFields();
$seatWidths = array_map("intval", $this->restExplode($data['compatible_seatwidth'] ?? [], true));
$compatibleProducts = $this->restExplode($data['compatible_product'] ?? null);
$incompatibleProducts = $this->restExplode($data['incompatible_product'] ?? null);
$requiredProducts = $this->restExplode($data['required_product'] ?? null);
$preConditions = $this->parsePreCondition($data['pre_condition'] ?? null);
$wheelSizes = array_map("intval", $this->restExplode($data['wheel_sizes'] ?? [], true));
$backHeights = array_map("intval", $data['back_height'] ?? []);
$casterSizes = array_map("intval", $data['caster_sizes'] ?? []);
$seatHeights = array_map("intval", $data['seat_heights'] ?? []);
$seatDepths = array_map("intval", $data['seat_depths'] ?? []);
$dropdownValues = $data["dropdown_values"] ?? null;
list($countPerGroup, $optionGroup) = $this->parseCountPerGroupAndOptionGroup($data['count_per_group'] ?? null);
return [
"id" => $product->getId(),
"name" => $product->getTranslation("name"),
// TODO Use thumbnails?
"cover" => $this->getThumbnail(
$context, $product->getCover()?->getMedia(),
200,
200
),
'productNumber' => $product->getProductNumber(),
"canHide" => $canHide,
'hint' => null, // TODO
"productGroup" => $data['product_group'] ?? null,
'productDescription' => $data['product_description'] ?? null,
'displayType' => $data['display_type'] ?? null,
'displayValue' => $data['display_value'] ?? null,
"seatWidths" => $seatWidths,
// Don't output compatible products, since they are not used
// 'compatibleProducts' => $compatibleProducts,
'compatibleProducts' => [],
'incompatibleProducts' => $incompatibleProducts,
'requiredProducts' => $requiredProducts,
'countPerGroup' => $countPerGroup,
'optionGroup' => $optionGroup,
'outputOrder' => $data['output_order'] ?? null,
'configuratorTab' => $data['configurator_tab'] ?? null,
'configuratorTabSection' => $data['configurator_tab_section'] ?? null,
'preCondition' => $preConditions,
'wheelSizes' => $wheelSizes,
'requiredSelections' => $data['required_selection'] ?? [],
'backHeights' => $backHeights,
'casterSizes' => $casterSizes,
'seatHeights'=> $seatHeights,
'seatDepths' => $seatDepths,
'dropdownValues' => $dropdownValues,
'description' => $product->getDescription(),
'smallHint' => $data["small_hint"] ?? null,
];
}
/**
* @Route("/hoggi-configurator/{configuratorId}", name="frontend.hoggi-configurator.page", methods={"GET"}, defaults={"_loginRequired"=true})
*/
public function hoggiConfiguratorPage(Request $request, Cart $cart, SalesChannelContext $context): Response
{
$page = $this->configuratorPageLoader->load($request, $cart, $context);
return $this->renderStorefront('@SwagHoggi/storefront/page/hoggi-configurator/index.html.twig', [
'page' => $page
]);
}
/**
* @Route("/hoggi-configurator/configurations/list", name="frontend.hoggi-configurator.saved-configuration.list", methods={"GET"}, defaults={"_loginRequired"=true})
*/
public function savedConfigurationListingPage(Request $request, SalesChannelContext $context): Response
{
$page = $this->savedConfiguratorListingPageLoader->load($request, $context);
return $this->renderStorefront('@SwagHoggi/storefront/page/hoggi-configurator/saved-configuration-listing.html.twig', [
'page' => $page
]);
}
/**
* @Route("/hoggi-configurator/configurations/remove/{configurationId}", name="frontend.hoggi-configurator.saved-configuration.remove", methods={"GET"}, defaults={"_loginRequired"=true})
*/
public function savedConfigurationRemovePage(Request $request, Cart $cart, SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
$configurationId = $request->attributes->get("configurationId");
$configurationCriteria = (new Criteria())->setLimit(1)
->setIds([$configurationId])
->addFilter(new EqualsFilter("customerId", $customer->getId()));
$configurationEntity = $this->savedConfigurationRepository->search($configurationCriteria, $context->getContext())->first();
if (!$configurationEntity) {
$this->addFlash("danger", "Die Konfiguration existiert nicht");
} else {
$this->savedConfigurationRepository->delete([
[
"id" => $configurationId
]
], $context->getContext());
$this->addFlash("success", "Die Konfiguration wurde gelöscht");
}
return $this->redirectToRoute('frontend.hoggi-configurator.saved-configuration.list');
}
private function findProductInDataByProductNumber(array $productData, string $productNumber): ?array {
foreach ($productData as $product) {
if ($product["productNumber"] === $productNumber) {
return $product;
}
}
return null;
}
/**
* @param Request $request
* @param SalesChannelContext $context Current context
* @return Response
* @Route("/hoggi-configurator/save-configuration", name="frontend.hoggi-configurator.save-configuration", methods={"POST"}, defaults={"csrf_protected"=false, "XmlHttpRequest"=true})
*/
public function saveConfiguration(Request $request, SalesChannelContext $context): Response {
/** @var string $name */
$name = $request->request->get("name");
/** @var string|null $savedConfigurationId */
$savedConfigurationId = $request->request->get("savedConfigurationId");
/** @var array $configuration */
$configuration = $request->request->get("configurator") ?: [];
/** @var string $configuratorId */
$configuratorId = $request->request->get("configuratorId");
/** @var CustomerEntity|null $customer */
$customer = $context->getCustomer();
if (empty($name)) {
$name = "Unbekannt";
}
if (empty($configuration)) {
throw new RuntimeException("No configuration data!");
}
if (empty($configuratorId)) {
throw new RuntimeException("No configurator id!");
}
if ($customer == null) {
throw new RuntimeException("Not logged in!");
}
$configuratorCriteria = (new Criteria([$configuratorId]))->setLimit(1);
/** @var ConfiguratorEntity|null $configuratorEntity */
$configuratorEntity = $this->configuratorRepository->search($configuratorCriteria, $context->getContext())->first();
if ($configuratorEntity == null) {
throw new RuntimeException("Configurator '$configuratorId' not found");
}
if ($savedConfigurationId != null) {
$existingCriteria = (new Criteria())
->setLimit(1)
->setIds([$savedConfigurationId])
->addAssociation("configurator")
->addAssociation("customer");
/** @var SavedConfigurationEntity|null $existingEntity */
$existingEntity = $this->savedConfigurationRepository->search($existingCriteria, $context->getContext())->first();
} else {
$existingEntity = null;
}
if ($existingEntity != null) {
if ($existingEntity->getConfigurator()->getId() !== $configuratorEntity->getId()) {
throw new RuntimeException("Different configurator!");
}
if ($existingEntity->getCustomer()->getId() !== $customer->getId()) {
throw new RuntimeException("Different customer!");
}
if ($existingEntity->getWasOrdered()) {
throw new RuntimeException("Has been ordered already!");
}
$this->savedConfigurationRepository->update([
[
"id" => $savedConfigurationId,
"name" => $name,
"layout" => $configuratorEntity->getLayout(),
"configuration" => $configuration
]
], $context->getContext());
$result = [
"savedConfigurationId" => $savedConfigurationId,
"savedConfigurationName" => $name
];
} else {
$newId = Uuid::randomHex();
$this->savedConfigurationRepository->create([
[
"id" => $newId,
"configuratorId" => $configuratorId,
"customerId" => $customer->getId(),
"wasOrdered" => false,
"name" => $name,
"layout" => $configuratorEntity->getLayout(),
"configuration" => $configuration
]
], $context->getContext());
$result = [
"savedConfigurationId" => $newId,
"savedConfigurationName" => $name
];
}
return new JsonResponse($result);
}
}