Struggling with enhanced custom quantity/price plugin

  • Posts: 29
  • Thank you received: 2
2 years 8 months ago #340031

-- HikaShop version -- : 4.4.5
-- Joomla version -- : 4.1
-- PHP version -- : 7.4

Hi,

Inspired by the "HikaShopCustom Quantity plugin" plugin, I'm working on an enhanced version. I am implementing an onBeforeCalculateProductPriceForQuantity event handler to adjust price and/or quantity values, but run into all sorts of problems. The two most important things I'm currently struggling with are:

- I have a product with several variations and associated prices. When I add the product to the cart, the onBeforeCalculateProductPriceForQuantity event is triggered multiple times, 6 to be exact, but each time with a different product, alternating between "variant" and "main" product. This seems rather odd and I have no clue what to do at each of those event invocations.

- I also have a few custom text fields for the product. How can I access the input of those fields in the onBeforeCalculateProductPriceForQuantity event handler? On some invocations they appear to be in the POST data[item], but not on all invocations.

The general idea is to either use the price of the select variant or, if no variant is chosen, use the manual input from a width and length field to calculate the price. Do you have any suggestions how to approach this?

Please Log in or Create an account to join the conversation.

  • Posts: 29
  • Thank you received: 2
2 years 8 months ago #340034

This post should have been in the Development section. I have no idea why it ended up here and I don't see a way to move it to the proepr place.

Last edit: 2 years 8 months ago by pjdevries.

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 years 8 months ago #340033

Hi,

The event onBeforeCalculateProductPriceForQuantity is not triggered when a product is added to the cart.
It is triggered for each product in the cart when the cart is loaded. So during an add to cart, you'll have it triggered for each product in the cart before the product is added to the cart (becaue to add a product to the cart, the cart must first be loaded), and then after the product is added, the cart will be reloaded.
So it's normal that you don't see the input of the custom fields in the POST, since the onBeforeCalculateProductPriceForQuantity event will be called everywhere where the cart is loaded, regardless of whether a product is being added or not.

In that event, the data of the product will be in $product.
So if you have a custom item field with the column name "my_field", you'll have the value entered by the user in $product->myfield
And to know if the current $product is a variant or a main product, you can check $product->product_type which can be either "main" or "variant".

The following user(s) said Thank You: pjdevries

Please Log in or Create an account to join the conversation.

  • Posts: 29
  • Thank you received: 2
2 years 8 months ago #340074

Thanx for your reply. It helps, but I am still confused about many things. From your explanation I gather that I must take another approach. Not entirely different, because I will still need the onBeforeCalculateProductPriceForQuantity event to do custom calculations. But there are circumstances in which I simply have to replace a product with another. More specifically I must sometime replace a variant with the main product. I assume this can be done in an onBeforeCartSave event handler. However, there is something confusing about the cart data I receive in that handler. When the cart is empty, onBeforeCartSave receives an element in which attribute cart_products is an array., containing a single product object with very limited attributes. It does not have a `product_type` attribute for instance. When adding exactly the same product to the cart, the contents of $element->cart_products is quite different. Not only is it no longer an array but an object, but the products within have more attributes. They all have a `product_type` for instance.

Is there a specific reason for these inconsistencies in the HikaShop API? Do you have any advice how best to approach my challenge?

Last edit: 2 years 8 months ago by pjdevries.

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 years 8 months ago #340085

Hi,

onBeforeCartSave is called by the save function in class.cart
If I write such code somewhere:

$cart = new stdClass();
$cartClass->save($cart);
it will save a new cart to the database with nothing in it.
And when the onBeforeCartSave event will be called by the save function, you will have an object with attributes added automatically to it, like the session_id or user_id, the cart_type, etc but you won't have an cart_products attribute at all since the code calling the save function won't provide it.
That doesn't mean that there is a problem with the code triggering onBeforeCartSave in the save function of class.cart, or even with the code calling the save function.
It's just that you can't trust that you'll always get the data in $element so you need to add extra checks for those cases.
For example, if you're missing the product_type and you need it, you can run such code:
$productClass = hikashop_get('class.product');
$productData = $productData = $productClass->get($cart_product->product_id);
echo $productData->product_type;

Please Log in or Create an account to join the conversation.

  • Posts: 29
  • Thank you received: 2
2 years 8 months ago #340111

Thanx again Nicholas. Bit by bit I'm getting closer :)

Just to be sure: is there no problem with me swapping one product for another in the onBeforeCartSave event handler? If not, is there a specific HikaShop way of doing that, some kind of API call, or should I simply manipulate the cart object and the product objects within it directly?

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 years 8 months ago #340114

Hi,

You can directly manipulate $element, yes. And make sure you have the & in the function parameters. That way, what you change in $element will be seen by the save function and HikaShop will save the products the way you want them.

The following user(s) said Thank You: pjdevries

Please Log in or Create an account to join the conversation.

Time to create page: 0.064 seconds
Powered by Kunena Forum