使用Sylius,我想在用户购买另一个产品时通过Ajax将产品添加到购物车中。
我尝试了对Sylius OrderItemController的ajax调用,但是由于尝试进行重定向而总是返回500 http错误,所以我不想这样做。
这是我已经完成的工作,但仍在工作,但是我认为这必须是一种更好的方法,因为我认为这对于实现功能的代码来说应该更为简单:
在这里,我选择单击第一个产品的用户操作,通过ajax调用一个将产品添加到购物车的控制器,然后如果响应正确,则在FormItemController中调用导致Sylius方法addAction的表单:
premiumItem.click(function() {
let formProduct = $("#sylius-product-adding-to-cart");
let formPremium = $("#sylius-premium-product-adding-to-cart");
let premiumProductId = formPremium.data('premiumProductId');
plansbutton.attr('disabled', 'disabled');
/* Ajax call to custom controller */
$.ajax({
url: "{{ path('sylius_shop_ajax_cart_add_item_premium') }}?productId="+premiumProductId,
method: 'POST',
dataType: "json",
})
.done(function() {
formProduct.submit(); // If ok, form to Sylius controller is called
})
.always(function() {
plansbutton.removeAttr('disabled');
});
});
在这里,我从请求中获取产品ID,并使用服务来获取变体并设置数量。完成后,订单将更新。
控制器:
/**
* @param Request $request
* @return JsonResponse
*/
public function addPremiumServiceAction(Request $request)
{
$cartProvider = $this->get("sylius.context.cart");
try {
/** @var Order $cart */
$cart = $cartProvider->getCart();
} catch (CartNotFoundException $exception) {
$cart = null;
}
if($this->get('opos.sylius_integration.service.order_service')->addProductVariantToCart($cart, $request->get('productId'))) {
$em = $this->getDoctrine()->getManager();
$em->persist($cart);
$em->flush($cart);
return new JsonResponse(array('result' => 'Order updated'), 200);
} else {
return new JsonResponse(array('result' => 'Order could not be updated'), 202);
}
}
服务:
/**
* @param Order $cart
* @param $productId
* @return mixed
*/
public function addProductVariantToCart(&$cart, $productId)
{
$productVariant = $this->productVariantRepository->find($productId);
/** @var OrderItem $orderItem */
$orderItem = new OrderItem();
$orderItem->setVariant($productVariant);
if(!$this->checkRepeatedItemsInCart($cart, $orderItem)) {
$this->orderItemQuantityModifier->modify($orderItem, 1);
$this->orderModifier->addToOrder($cart, $orderItem);
$cart->addItem($orderItem);
}
return $cart;
}