I am struggling to add a composite product to to WC orders programatically. I have been going through the source code to try and figure this out, but keep running into errors.
What I am doing right now is creating at instance of WC_CP_Order to get access to the method add_composite_to_order($composite, $order, $quantity, $args)
$wc_cp = new WC_CP_Order(); // Create instance of WC_CP_Order
$composite_product = wc_get_product('39082'); // Get the composite product
$order = wc_get_order(39250); // Order that I want to add the composite product to
$args = array(
'configuration' => array(
1620281459 => array( // ID of the component.
'quantity' => 1, // Qty of composited product, will fall back to min.
'discount' => 0, // Composited product discount, defaults to the defined value.
'attributes' => array(), // Array of selected variation attribute names, sanitized.
'variation_id' => 39114, // ID of chosen variation, if applicable.
'args' => array() // Custom composited item args to pass into 'WC_Order::add_product()'.
)
)
)
$wc_cp->add_composite_to_order($composite_product, $order, 1, $args);
This configuration returns a 500 error when I trigger this function (this is just all of the code inside the function).
I am probably just overlooking something very simple, but so far am unable to find it. There are the docs that I have been using: https://docs.woocommerce.com/document/composite-products/. Any help or suggestions would be greatly appreciated!!
Related
I am using the following code to add attributes to a product:
$product_attr = get_post_meta(2, '_product_attributes',true);
$product_attr["pa_product-type"] = [
'name' => "pa_product-type",
'value' => '',
'is_visible' => '0',
'is_taxonomy' => '1'
];
wp_set_object_terms(2, "Caps", pa_product-type , true );
update_post_meta(2, '_product_attributes', $product_attr);
The attribute is getting updated successfully in the product and is showing up in product edit page. However, the attribute value is not getting updated in wp_wc_product_attributes_lookup table. How to trigger update in this table after updating/adding attributes using the above code?
This is a very interesting question!
The wp_wc_product_attributes_lookup table is used to improve WooCommerce performance and it's normally updated automatically. There is a class DataRegenerator that handles the product attributes regeneration process. But if you change the attributes directly in the wp_postmeta like this:
$product_id = 46;
$product_attr = get_post_meta($product_id, '_product_attributes',true);
$product_attr["pa_color"] = [
'name' => "pa_color",
'value' => '',
'is_visible' => '0',
'is_taxonomy' => '1'
];
wp_set_object_terms($product_id, "Blue", 'pa_color' , true );
update_post_meta($product_id, '_product_attributes', $product_attr);
then the wp_wc_product_attributes_lookup table is not updated immediately.
But you can trigger this update manually by using LookupDataStore class.
First you add
use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore;
outside your function, for example on the top of the plugin or theme php file or just above your add_action line.
Then you can call the function to create product attributes in the lookup table for a specific product_id
$lookupDataStore = new LookupDataStore();
$lookupDataStore->create_data_for_product($product_id);
Source
I need to show one certain product on front page. I didn't find a module for this. What do I need to do? I need to show product with countdown timer but I can do this, I only do not know how to get product from database by ID or SKU. I guess the code should be like this:
echo $product_option_data[] = array(
'product_option_id' => $product_option['product_option_id'],
'option_id' => $product_option['option_id'],
'name' => $product_option['name'],
'type' => $product_option['type'],
'option_value' => $product_option['option_value'],
'required' => $product_option['required']
);
In OpenCart controller you can call
$this->load->model('catalog/product'); // only if not yet 'loaded' within the controller
$product = $this->model_catalog_product->getProduct($productId);
print_r($product);
which will return you the product by it's ID. Do with it whatever you need afterwards.
I've got the following code:
$filters = array('sku' => array('like'=>'%'));
$items = $magConn->call($sessionID, 'product.list', array($filters));
This will return an array of all the products and their sku, description, and qty.
However, I also need to get the price? Is there a way to get that as well?
I've also got this working,
$properties = ($magConn->call($sessionID, 'product.info', $item['sku']));
which will return all the attributes for one product. I've got over 2,000 products, and this is definitely not feasible if I want it to end tonight. ;)
No way without magento source code modification. You should go to \app\code\core\Mage\Catalog\Model\Product\Api.php, find next lines inside items() method:
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids' => $product->getCategoryIds()
);
and add price here.
Load the collection :
$product = Mage::getModel('catalog/product')->load($productId);
Get actual price :
$product->getPrice();
Get special price :
$product->getFinalPrice();
I'm trying to get bundle options data. using this : $product->getBundleOptionsData I need to use this, as I'm trying to change data programmatically and I would like to do it in a way that's as close as used in admin .
However, when I var_dump the result of the above function I get NULL while in admin side in bundle model product type I get correctly the data.
When I var_dump $product in my own file I get much shorter data than when I var_dump in bundle model product type save function.
what do I need to do to load all data of the product, so I can use getBundleOptionsData. I looked in several files and googled, but can't find an answer.
Finally I made it work to get bundle options data so I can manipulate it. I found the main code in magento's model bundle observer class duplicateProduct function: I needed however to add option_id (careful not to forget that)
here is the code in it's final stage.
$product->getTypeInstance(true)->setStoreFilter($product->getStoreId(), $product);
$optionCollection = $product->getTypeInstance(true)->getOptionsCollection($product);
$selectionCollection = $product->getTypeInstance(true)->getSelectionsCollection(
$product->getTypeInstance(true)->getOptionsIds($product),
$product
);
$optionCollection->appendSelections($selectionCollection);
$optionRawData = array();
$selectionRawData = array();
$i = 0;
foreach ($optionCollection as $option) {
$optionRawData[$i] = array(
'option_id' => $option->getOptionId(), //my addition. important otherwise, options going to be duplicated
'required' => $option->getData('required'),
'position' => $option->getData('position'),
'type' => $option->getData('type'),
'title' => $option->getData('title')?$option->getData('title'):$option->getData('default_title'),
'delete' => ''
);
foreach ($option->getSelections() as $selection) {
$selectionRawData[$i][] = array(
'product_id' => $selection->getProductId(),
'position' => $selection->getPosition(),
'is_default' => $selection->getIsDefault(),
'selection_price_type' => $selection->getSelectionPriceType(),
'selection_price_value' => $selection->getSelectionPriceValue(),
'selection_qty' => $selection->getSelectionQty(),
'selection_can_change_qty' => $selection->getSelectionCanChangeQty(),
'delete' => ''
);
}
$i++;
}
$product->setBundleOptionsData($optionRawData); //changed it to $product
$product->setBundleSelectionsData($selectionRawData); //changed it to $product
you can either now change on the raw data in optionsrawdata. or getBundleOptionsData. and same for the other one.
Alright, so I'm working on my own script that reads specific xml files, and imports products. Now, each of these products may have a set of attributes, (i.e. color for example).
So, what I'm doing is importing each custom attribute, and generating a specific string, "Yellow, black finish wood" for example, and that would be a radio button you could select from when you go to order the product. Now, when I come to a product that has the same "parentid" but a different unique id, I need to generate a new row for the custom option radio button, so if there is another product where the color is red, I would have the following to select from:
Red, black finish wood
Yellow, black finish wood
This is working great for the first product with the same parent id, in other words, if I'm creating a brand new product, and not just adding custom options to the same product.
My question is, how do I generate a new custom option value, for the specific option? In other words, how do I add a new row to a certain option that is already created?
Here is basically what I'm doing to generate the first option on a new product.
$options = array();
$options[$ParentID] = array(
'title' => 'Option Title',
'type' => 'radio',
'is_require' => 1,
'values' => array()
);
$options[$ParentID]['values'][] = array(
'title' => 'Option Value Title',
'price' => 0.00,
'price_type' => 'fixed',
'sku' => $UniqueID,
);
foreach($options as $ParentID => $option) {
$id = Mage::getModel('catalog/product')->getIdBySku($ParentID);
$product = Mage::getModel('catalog/product')->load($id);
if(!$product->getOptionsReadonly()) {
$product->setProductOptions(array($option));
$product->setCanSaveCustomOptions(true);
$product->save();
}
}
this works out great, because magento generates an sku when they order a certain product in the format of $ParentID_$UniqueID, and then I can send the $UniqueID off to the vendor for the order.
So again, I'm open to suggestions as to how to add a Option Value to an already created Custom Option
load all options in and create array map with unique and already existing options to get their id -s in place