Creating variants programmatically

  • Posts: 9
  • Thank you received: 1
4 months 2 weeks ago #361937

-- HikaShop version -- : 5.1.0
-- Joomla version -- : 4.4.5

Hello,
I want to create products in a plugin which can be either parents or variants (children)
I've got running the basics of creating a product with categories etc. and I know that characteristics are used to specify variants.
Here are my questions:
*when I create a parent, I need to specify whch characteristic(s) can be used to create a variant and the default value for each. I suspect that I must use $productClass->updateCharacteristics but how ?
*when I create a variant I set its parent with something like $product->product_parent_id = 127 (looking at the code for ->save() in classes/product.php. The product_type is then set automatically). I also need to specifiy the actual value of each characteristic but how?
Advice from seasoned programmers would be appreciated, thank you

Last edit: 4 months 2 weeks ago by DomB22.

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

  • Posts: 82867
  • Thank you received: 13373
  • MODERATOR
4 months 2 weeks ago #361943

Hi,

You don't need to set product_parent_id in each variant. However, when calling the updateCharacteristics function, you need to provide the product_id of the product in the second parameter. Also, you should set the third parameter to 2.

The call to updateCharacteristics in the save function is used to generate the link between the product and the characteristics, as well as the link between the product and the default value of each characteristic, so it's not a good example of how to call updateCharacteristics to generate the variants of a product selectively.
I would rather recommend looking at the populateVariant function. That's the function called by HikaShop when you use the "add variants" button and you select the characteristics and the values for which you want the variants to be generated. In it, you can see that it does two things before calling updateCharacteristics. First, it fills $elem->oldCharacteristics with the result of a call to getProductCharacteristics. This provide the data of the characteristics linked to the product. Second, it fills the $elem->characteristics array with objects, one per characteristic, and in each object, an array of values in the values attribute.
I think this fits a lot better to what you're trying to do.
Note that this will basically create the variant entry in the hikashop_product table, and the links between each variant and its corresponding value for each characteristic in the hikashop_variant table. Then, you still need to save each variant individually if you wish to provide data for each variant with the save function.

The following user(s) said Thank You: DomB22

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

  • Posts: 9
  • Thank you received: 1
4 months 2 weeks ago #362019

Thank you NIcolas. So with ->populateVariant I managed to create a variant linked to its parent and to a set of (characteristic, values) tuples. I still have two questions :
- How do I get the product_id of the newly created variant product as it is not returned by populateVariant ?
- When I create the parent product, how do I specify the list of characteristics to be used to instantiate child variants ? It does not seem to be with ->addCharacteristic as the method requires both a characterisic_id and a characterisic_value_id in its arguments
If my question is not clear enough I can give an example

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

  • Posts: 82867
  • Thank you received: 13373
  • MODERATOR
4 months 1 week ago #362032

Hi,

1. The populateVariant function doesn't provide that capability as it is not needed by HikaShop. Thus, you would have to run a MySQL query on the hikashop_product table in order to get the product_id of the variants.

2. So, before you use the populateVariant function to generate the variants, you indeed first need to link the parent product with the characteristics. You can call the updateCharacteristics function with your $product object with an attribute characteristics, which is an array like this:

$firstCharacteristic = new stdClass();
$firstCharacteristic->characteristic_id = 1; // id of the characteristic in the hikashop_characteristic table
$firstCharacteristic->default_id = 2; // id of the default value in the hikashop_characteristic table

$secondCharacteristic = new stdClass();
$secondCharacteristic->characteristic_id = 2;
$secondCharacteristic->default_id = 4;

$product->characteristics = array(
  $firstCharacteristic->characteristic_id => $firstCharacteristic,
  $secondCharacteristic->characteristic_id => $secondCharacteristic,
);

// then, you can call updateCharacteristics on $product
Of course you need to adapt the values in the attributes of the characteristic objects to match with what you have on your website.

The following user(s) said Thank You: DomB22

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

  • Posts: 9
  • Thank you received: 1
4 months 6 days ago #362166

Thank you Nicolas, I think I'm nearly there, I finally got it working with these remarks :
* I had to add values to $xxCharacteristic->ordering , should it start with 0 or 1?
* for some reason, passing auto_variants=2 to updateCharacteristics failed but with auto_variants=0 it worked. I was not explicit in my initial request but in my case both the variants and their possible values already exist in the hikashop_characteristics table

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

  • Posts: 82867
  • Thank you received: 13373
  • MODERATOR
4 months 6 days ago #362169

Hi,

You can set all the ordering to 0 I think and it will use the order in which you add them.
Otherwise, you can use incremental numbers starting at 1.

The following user(s) said Thank You: DomB22

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

  • Posts: 9
  • Thank you received: 1
4 months 6 days ago #362173

Maybe one more question: what would be the function call if I want to update the characteristics values of an existing variant/child product?

Last edit: 4 months 6 days ago by DomB22.

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

  • Posts: 82867
  • Thank you received: 13373
  • MODERATOR
4 months 6 days ago #362177

Hi,

You would use the same updateCharacteristics function with the $product->characteristics array set with the new characteristic values.
That's what is done in the backSaveVariantForm function of the same class which is called when you save a variant edit form in the backend since this interface allows you to change the values of a variant. So you can look in this backSaveVariantForm. Now, most of the code in there is irrelevant. It's the piece inside the

if(hikashop_acl('product/variant/characteristics')) {
which you want to look at.

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

Time to create page: 0.071 seconds
Powered by Kunena Forum