Skip to content

Instantly share code, notes, and snippets.

@cloudinstone
Created February 28, 2025 15:37
Show Gist options
  • Save cloudinstone/2941ded8e43b01f4a29b0ebc5f95d53b to your computer and use it in GitHub Desktop.
Save cloudinstone/2941ded8e43b01f4a29b0ebc5f95d53b to your computer and use it in GitHub Desktop.
WooCommerceProductUpdateHelper
<?php
namespace Semrock;
use WC_Product_Attribute;
class WooCommerceProductUpdateHelper
{
/**
* Update product attributes for a WooCommerce product
*
* @param int $product_id The product ID
* @param array $attributes Array of attributes with values
* @return bool Success status
*/
public function update_attributes(int $product_id, array $attribute_pairs, $override = false): bool
{
$product = wc_get_product($product_id);
if (!$product) {
return false;
}
$attributes = $override ? [] : $product->get_attributes();
foreach ($attribute_pairs as $name => $values) {
$slug = wc_sanitize_taxonomy_name($name);
$slug = substr($slug, 0, 28);
// Create attribute taxonomy if it doesn't exist
$taxonomy = $this->create_attribute_taxonomy_by_label($name);
if (!$taxonomy) {
continue;
}
// Prepare attribute values
$attribute_values = array();
foreach ($values as $value) {
$term = $this->create_term($value, $taxonomy);
if ($term && !is_wp_error($term)) {
$attribute_values[] = $term->term_id;
}
}
$id = wc_attribute_taxonomy_id_by_name($slug);
// Create attribute
$attribute = new WC_Product_Attribute();
$attribute->set_id($id);
$attribute->set_name($taxonomy);
$attribute->set_options($values);
// $attribute->set_position($data['position'] ?? 0);
$attribute->set_visible(true);
$attribute->set_variation(false);
$attributes[$taxonomy] = $attribute;
}
// Update product attributes
$product->set_attributes($attributes);
$product->save();
return true;
}
public function update_attribute_pairs(int $product_id, array $attribute_pairs): bool
{
$attribute_data = [];
foreach ($attribute_pairs as $name => $values) {
$attribute_data[] = $this->prepare_attribute_data($name);
}
$this->update_attributes($product_id, $attribute_data);
}
/**
* Create attribute taxonomy if it doesn't exist
*
* @param string $name Attribute name
* @return string|false Taxonomy name or false on failure
*/
private function create_attribute_taxonomy_by_label(string $label): string|false
{
$slug = wc_sanitize_taxonomy_name($label);
$slug = substr($slug, 0, 28);
$taxonomy_name = wc_attribute_taxonomy_name($slug);
if (taxonomy_exists($taxonomy_name)) {
return $taxonomy_name;
}
// Prepare attribute data
$attribute_data = array(
'name' => $label,
'slug' => $slug,
'type' => 'select',
'order_by' => 'menu_order',
'has_archives' => false,
);
// Create attribute
$result = wc_create_attribute($attribute_data);
if (is_wp_error($result)) {
return false;
}
// Register the taxonomy
register_taxonomy(
$taxonomy_name,
array('product'),
array(
'label' => $label,
'rewrite' => false,
'hierarchical' => false,
)
);
return $taxonomy_name;
}
/**
* Get existing term or create new one
*
* @param string $value Term value
* @param string $taxonomy Taxonomy name
* @return \WP_Term|null Term object or null
*/
private function create_term(string $value, string $taxonomy): ?\WP_Term
{
$term = get_term_by('name', $value, $taxonomy);
if (!$term) {
$result = wp_insert_term($value, $taxonomy);
if (!is_wp_error($result)) {
$term = get_term_by('id', $result['term_id'], $taxonomy);
}
}
return $term ?: null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment