我們接觸著昨天的尾端,我們做了能夠碰到了價格的hook,再次抱怨wooCommerce的docs真的是很不友善,我們使用的價錢的功能,要在我們使用的地方告一個段落,接著我們今天的目標就是將前端顯示的價格,與進到購物車的後端價格做一個確切的變化與更正,而並且在最後加入到購物車中,這樣就可以小小的動態調整價錢功能啦!而對了,我們的外掛的模板是參考WooCommerce Dynamic Pricing來的,價格很驚人,不過可以省你很多時間去開發這個,這個項目是真的滿複雜的!
我們現在在我們的產品頁面中加入新的action,來專門處理我們計算前端的價格,並且撰寫Javscript來處理價格的置換,而我們這邊使用的價錢,並不會直接進到後端,我們的後端為了安全性問題,我們仍然使用當下的參數來做第二次得價錢計算,而在目前這裡,我們會取代顯示的價錢,但是價錢在進到點擊submit時,仍然是以我們當初輸入的價錢。
add_action('init','go_ranger_wc_init');
function go_ranger_wc_init(){
wp_register_script(
'go-ranger-calculator',
plugin_dir_url( __FILE__ ) . '/post.js',
array(),
'1.0.0',
true
);
}
add_action('woocommerce_before_add_to_cart_form','go_ranger_variation');
function go_ranger_variation(){
wp_enqueue_script( 'go-ranger-calculator' );
global $product;
$show_content = $product->get_meta('go_ranger_enrave');
if($show_content){
?>
<style>
.price{
display:none;
}
.price.go-ranger-price{
display:block;
}
</style>
<div class="go-ranger-flex" style="display:flex;justify-content:space-around;align-items:center;">
<span>刻字在這,加些錢錢</span>
<input type="text" data-go-ranger-name="engrave" id="go_ranger_engrave">
</div>
<p class="price go-ranger-price">
<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span><span class="go-ranger-price-tag">990</span></bdi></span>
</p>
<?php
}
}
window.onload = function () {
let go_ranger_engrave = document.getElementById('go_ranger_engrave');
let price_tag = document.getElementsByClassName('go-ranger-price-tag')[0];
go_ranger_engrave.addEventListener('change', function (event) {
// 在這裡拿到
})
}
那我們目前就已經有了將正常的價格隱藏,並且顯示出我們做出來的模擬價格,而如果你的目的是要做會員登入才使用購物車,又要十足弔胃口的話,應該是要由可以購買的hook與新增新的價格的action動手做,這裡如果加上限定role才可以購買這類的功能,是滿熱門的操作手法。
那我們開始,先將正常的價格放上,並且撰寫js的邏輯來計算我們的刻字服務,假如沒有字則不需要多收費,如果有則是一百五十元,那我們使用wc_get_price_to_display
來取得我們的價錢,並且寫入預設的價錢,並且使用localize的功能,將我們這邊需要取得的參數帶入js之中。
$price = wc_get_price_to_display($product);
wp_enqueue_script( 'go-ranger-calculator' );
wp_localize_script(
'go-ranger-calculator' ,
'go_ranger_object',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'price' => $price
) );
.
.
.
<p class="price go-ranger-price">
<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span><span class="go-ranger-price-tag"><?php echo $price; ?></span></bdi></span>
</p>
window.onload = function () {
const DISPLAY_PRICE = go_ranger_object.price;
let go_ranger_engrave = document.getElementById('go_ranger_engrave');
let price_tag = document.getElementsByClassName('go-ranger-price-tag')[0];
go_ranger_engrave.addEventListener('change', function (event) {
let change_context = this.value.match(/a-zA-Z0-9/);
if (change_context) {
r_sir_change_price(price_tag);
} else r_sir_replace_price_tag(price_tag, DISPLAY_PRICE);
})
}
function r_sir_change_price(price_tag) {
target_price = DISPLAY_PRICE + 150;
r_sir_replace_price_tag(price_tag, target_price);
}
function r_sir_replace_price_tag(target_tag, target_price) {
target_tag.innerHTML = target_price;
}
我們現在在我們的產品頁面中加入第二個的action,我們的前端價格計算,就暴露在js前面,是有可能被打破的,所以不要傻呼呼的像當初某家購物網站,直接把前端的價錢送到後端都不做比對,我們在進到後端,是直接呼叫woocommerce_add_to_cart
來對加入購物車的價格做驗證,而我們在這邊可以再多掛一個新的價格,來做到更好的延伸。
add_action('woocommerce_add_to_cart', 'go_ranger_callback', 20, 6);
function go_ranger_callback($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data){
global $woocommerce;
foreach(WC()->cart->get_cart() as $cart_item_key => $values){
$cartItemPrice = $values['data']->get_price();
$values['data']->set_price(calculator_set_price($cartItemPrice,$cart_item_data,$quantity));
}
}
function calculator_set_price($cartItemPrice,$cart_item_data,$quantity){
$cart_item_data->get_meta('go_ranger_engrave');
if(!empty($cart_item_data)) return ($cartItemPrice + 150 ) * $quantity;
return $cartItemPrice * $quantity;
}
這樣價格進到購物車後,就會是正確的價格,而這個外掛的可能性,無非加入更多複雜的價格公式,而在公式的計算理想是建立class來專門處理這些模擬出來的價錢並且推算,並且有下列幾種的helper,能夠更加的完整。
來處理所有的價格轉換,並且還有ajax callback這一些地係向,並且將我們有提供到的模擬價格部分,都是由這個class來建立並輸出。
在每個頁面之中,你不可能只使用原生的延伸,更有可能是需要建立自己的購物欄位,或是特別的loop。
你在自己的外掛,總會有自己的後台頁面,但是在這種比較高複雜的部分之中,一個基本的class能夠涵蓋是對於維護與後續發展又更好的幫助的,比如說再動用到option API的時候,更可以有自己的handler來處理。
而我們的訂單總會有一些meta需要產生,而有時簡單有時就複雜,有時候你可能得將meta的輸出有模板的輸出,並且在出invoice或是reciept可以有更好的支援,這個在很多外掛都會有類似的應用,雖然名稱可能不叫這個,但是功能類似。
最後,這是你要將產品的加入的項目,寫入的公式,是否開啟,又有什麼特殊的需求,比如說一個然在限購或是產品本身打五折,但是多的服務是沒有折扣的這些比較實際面的應用。
我們可以做一個專門處理role與折扣的,因為折扣的公式並不單純,所以他是可以與priceHelper做一個很好的相依,在正確的role上做出正確的折扣。
最後,這一個簡單的應用,如果是使用ajax callback,並且回到產品頁面來做,應該可以免於價格更改時候刻意改動數字,這東西寫著寫著發現也是不少類似的外掛可以參考,不過都是要收錢的啦XD 我總覺得自己沒有找到一直能動態更改order價錢的hook,這樣的做法是太過於粗糙,如果往後有新的發現,我會繼續在其他地方把這個小外掛給發表出去。
明天我們來講講外掛開發後,總不能射後不理吧,該如何維護等等的注意事項,而在講完後,我預計繼續來做WooCommerce - Nested Category Layout,看到這個價錢很驚人,不知道是否除了加入模板與loop之餘,還有什麼地方是需要去注意的,否則怎麼可以有這麼貴的價格XD
WC-Product
WooCommerce Visual Hook Guide: Single Product Page
how to use ajax in wiordpress
wbe design industry jargon glossary and resources