本篇文章更新時間:2019/02/16
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
這個方法其實也滿多人討論的,主要是看用在哪,主要有兩派。一個是透過 REST API 的呼叫來建立,另一個是直接針對資料庫操作。
標題說的「建立或更新」是比較通泛的寫,但我的需求是「建立不然就是更新」商品。這時候 REST API 的方法就不適用了!
// 商品資料結構
$product_data = array(
'sku' => 'MXP_TW', //貨號
'product_name' => 'MXP_TW', //商品 Slug
'product_content' => 'content', //商品內容
'product_excerpt' => 'excerpt', //商品摘要
'regular_price' => '123', //售價
'purchase_note' => '購買備忘錄',
'virtual' => 'yes', //虛擬簡單商品
'downloadable' => 'yes', //可以下載的簡單商品
'downloadable_files' => array('file-id' => array('id' => 'file-id', 'name' => 'PDF', 'file' => 'https://www.mxp.tw/path/to/file.pdf')), //下載的檔案設定
);
// 建立或更新商品的方法(根據商品 Slug)
function create_or_update_product($product_data) {
global $wpdb;
$post_id = '';
if (!isset($product_data['product_name']) || $product_data['product_name'] == "") {
return false;
}
$res = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}posts WHERE post_name = %s AND post_type = 'product'", $product_data['product_name']), ARRAY_A);
$args = array(
'post_author' => 1,
'post_content' => $product_data['product_content'],
'post_status' => "publish",
'post_title' => $product_data['product_name'],
'post_parent' => '',
'post_type' => "product",
'post_excerpt' => $product_data['product_excerpt'],
);
if (count($res) >= 1) {
$post_id = $res[0]['ID'];
$args['ID'] = $post_id;
// 有此商品了就更新商品
wp_update_post($args);
} else {
// 建立商品
$post_id = wp_insert_post($args);
}
// 簡單商品
wp_set_object_terms($post_id, 'simple', 'product_type');
// 商品分類管理
wp_set_object_terms($post_id, '某個分類名稱', 'product_cat');
// 商品其他屬性
update_post_meta($post_id, '_sku', $product_data['sku']);
update_post_meta($post_id, '_regular_price', $product_data['regular_price']);
update_post_meta($post_id, '_price', $product_data['regular_price']);
update_post_meta($post_id, '_purchase_note', $product_data['purchase_note']);
update_post_meta($post_id, '_virtual', $product_data['virtual']);
update_post_meta($post_id, '_downloadable', $product_data['downloadable']);
update_post_meta($post_id, '_downloadable_files', $product_data['downloadable_files']);
update_post_meta($post_id, '_product_version', WC()->version);
update_post_meta($post_id, '_stock', 0);
update_post_meta($post_id, '_stock_status', 'onbackorder');
update_post_meta($post_id, '_manage_stock', 'yes');
update_post_meta($post_id, '_backorders', 'yes');
// 下方為尚未實作的商品屬性
// update_post_meta($post_id, '_thumbnail_id', $product_data['']);
// update_post_meta($post_id, '_sale_price', $product_data['']);
// update_post_meta($post_id, '_sale_price_dates_from', $product_data['']);
// update_post_meta($post_id, '_sale_price_dates_to', $product_data['']);
// update_post_meta($post_id, '_download_limit', $product_data['']);
// update_post_meta($post_id, '_download_expiry', $product_data['']);
// update_post_meta($post_id, '_sold_individually', $product_data['']);
return $post_id;
}
Gist: link
針對資料庫去新增或修改商品的寫法如上,關鍵是針對商品的「Slug」做對應,畢竟脫離 WordPress 架構下還能當唯一識別的也就非 Slug 莫屬。
REST API 的解法可以參考這篇 Stack Overflow 討論 WooCommerce: Create product by code
既然是 REST API 就要知道,他的功能一次呼叫就是一個動作,也沒有能符合我需求的「建立不然就是更新」。
最後補一下「加入購物車」的兩種方式:
// 後端方式加入購物車的做法
global $woocommerce;
$woocommerce->cart->add_to_cart($product_id);
前端的做法如我先前文章提過的:[WooCommerce] 商品頁快速結帳按鈕功能
本篇提到的程式化也與這篇[WooCommerce] 客製化訂單與結帳流程的作法 會有點關係,一起提及記錄。