plugins-wp/wp-product-importer/includes/helpers/wpi-product-helper.php

228 lines
6.1 KiB
PHP

<?php
class WPI_Product_Mapper
{
public static function upsert($data)
{
if (empty($data['sku'])) return;
$product_id = wc_get_product_id_by_sku($data['sku']);
$product = $product_id
? wc_get_product($product_id)
: new WC_Product_Simple();
$product->set_name($data['name'] ?? '');
$product->set_sku($data['sku']);
$product->set_regular_price($data['price'] ?? 0);
$product->set_stock_quantity($data['stock'] ?? 0);
$product->set_manage_stock(true);
if (!empty($data['description'])) {
$product->set_description(wp_kses_post($data['description']));
}
if (!empty($data['short_description'])) {
$product->set_short_description(wp_kses_post($data['short_description']));
}
return $product->save();
}
protected static function attach_images(int $product_id, array $urls)
{
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$gallery_ids = [];
foreach ($urls as $index => $url) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
continue;
}
$attachment_id = media_sideload_image($url, $product_id, null, 'id');
if (is_wp_error($attachment_id)) {
continue;
}
if ($index === 0) {
set_post_thumbnail($product_id, $attachment_id);
} else {
$gallery_ids[] = $attachment_id;
}
}
if ($gallery_ids) {
update_post_meta(
$product_id,
'_product_image_gallery',
implode(',', $gallery_ids)
);
}
}
public static function upsert_from_api(array $data)
{
if (empty($data['sku'])) return;
$product_id = self::upsert($data);
if (!$product_id) return;
if (!empty($data['brand'])) {
self::sync_brand($product_id, $data['brand']);
}
if (!empty($data['categories'])) {
self::sync_categories($product_id, $data['categories']);
}
if (!empty($data['images'])) {
self::sync_images($product_id, $data['images']);
}
return $product_id;
}
protected static function sync_categories(int $product_id, array $categories)
{
if (empty($categories)) return;
$term_ids = [];
foreach ($categories as $cat_id) {
// chỉ nhận số
if (is_numeric($cat_id)) {
$term_ids[] = (int) $cat_id;
}
}
if (!$term_ids) return;
// gán trực tiếp, KHÔNG tạo mới
wp_set_object_terms(
$product_id,
array_unique($term_ids),
'product_cat'
);
}
protected static function sync_images(int $product_id, array $images)
{
if (empty($images)) return;
$urls = array_filter(array_map('trim', $images));
if (!$urls) return;
self::attach_images($product_id, $urls);
}
protected static function sync_brand(int $product_id, string $brand)
{
$brand = trim($brand);
if (!$brand) return;
$taxonomy = 'product_brand';
// Kiểm tra taxonomy tồn tại
if (!taxonomy_exists($taxonomy)) {
return;
}
// Check brand đã tồn tại chưa
$term = term_exists($brand, $taxonomy);
// Chưa có → tạo mới
if (!$term) {
$term = wp_insert_term($brand, $taxonomy);
}
if (is_wp_error($term)) {
return;
}
$term_id = (int) $term['term_id'];
// Gán brand cho product
wp_set_object_terms($product_id, [$term_id], $taxonomy);
// Đảm bảo attribute xuất hiện trong product
$product = wc_get_product($product_id);
if (!$product) return;
$attributes = $product->get_attributes();
if (!isset($attributes[$taxonomy])) {
$attr = new WC_Product_Attribute();
$attr->set_name($taxonomy);
$attr->set_options([$brand]);
$attr->set_visible(true);
$attr->set_variation(false);
$attributes[$taxonomy] = $attr;
$product->set_attributes($attributes);
$product->save();
}
}
protected static function create_wp_categories_from_tree(
array $categories,
int $parent_id = 0,
string $taxonomy = 'category'
) {
foreach ($categories as $item) {
if (empty($item['name']) || empty($item['id'])) {
continue;
}
$name = $item['name'];
$slug = sanitize_title($name);
$description = (string) $item['id']; // 👈 external ID
// Check if term exists under same parent
$existing = term_exists($slug, $taxonomy, $parent_id);
if ($existing) {
$term_id = is_array($existing)
? $existing['term_id']
: $existing;
// Update description if changed
wp_update_term($term_id, $taxonomy, [
'description' => $description,
]);
} else {
$result = wp_insert_term($name, $taxonomy, [
'slug' => $slug,
'parent' => $parent_id,
'description' => $description,
]);
if (is_wp_error($result)) {
error_log('[CATEGORY_SYNC] ' . $result->get_error_message());
continue;
}
$term_id = $result['term_id'];
}
// Recurse children
if (!empty($item['children']) && is_array($item['children'])) {
self::create_wp_categories_from_tree(
$item['children'],
$term_id,
$taxonomy
);
}
}
}
}