welcartのSKU入力欄を拡張する
SKUにカスタム入力項目を追加しました。functions.php内で完結しているのでwelcart本体に手をつけなくていいので安心。
※こちらで紹介している記述ではAuto Deliveryとバッティングします。定期購入機能の利用者はカスタマイズが必要です。
参考にしたサイト
今回のカスタマイズはこちらを参考にしました。
【Welcart】でSkuに新規項目を追加する方法|ゴーゴーウェブマーケット技術BLOG
こうやって情報を共有していただけるのは本当にありがたいことです。変更箇所は以下2点。
●更新時にSKUフィールドが消えないようにフィルターをひとつ追加。
●項目が一つしか追加できなさそうなのでtdを結合。
CODE : Adding a new field to SKUs on welcart
<?php
/////////////////////// WELCART SKU内に項目を追加 ///////////////////////
add_filter( 'usces_filter_sku_meta_form_advance_title', 'add_new_sku_meta_title'); //項目を追加
function add_new_sku_meta_title(){
return '<th colspan="2">カスタム項目</th>';
}
add_filter( 'usces_filter_sku_meta_form_advance_field', 'add_new_sku_meta_field'); //フィールドを新規追加
function add_new_sku_meta_field(){
return '<td colspan="2" class="item-sku-zaikonum"><input name="newskuadvance" type="text" id="newskuadvance" class="newskuadvance metaboxfield" /></td>'."n";
}
add_filter( 'usces_filter_sku_meta_row_advance', 'add_new_sku_meta_row_advance',10,2); //フィールドを追加
function add_new_sku_meta_row_advance( $default_field, $sku ){
$metaname = 'itemsku[' .$sku["meta_id"]. '][skuadvance]';
return '<td colspan="2" class="item-sku-zaikonum"><input name="' .$metaname.'" type="text" id="' .$metaname. '" class="newskuadvance metaboxfield" value="' .$sku["advance"]. '"/></td>'."n";
}
add_filter( 'usces_filter_add_item_sku_meta_value', 'add_new_sku_meta'); //新規項目を作成
function add_new_sku_meta($value){
$skuadvance = isset($_POST['newskuadvance']) ? $_POST['newskuadvance'] : '';
$value['advance'] = $skuadvance;
return $value;
}
add_filter( 'usces_filter_up_item_sku_meta_value', 'up_new_sku_meta'); //項目を変更
function up_new_sku_meta($value){
$skuadvance = isset($_POST['skuadvance']) ? $_POST['skuadvance'] : '';
$value['advance'] = $skuadvance;
return $value;
}
add_filter( 'usces_filter_item_save_sku_metadata', 'save_new_sku_meta',10,2 ); //項目を保持
function save_new_sku_meta( $skus, $mid ){
$skuadvance = isset($_POST['itemsku'][$mid]['skuadvance']) ? $_POST['itemsku'][$mid]['skuadvance']: '';
$skus['advance'] = $skuadvance;
return $skus;
}
?>
商品情報ページのループ内でuscesを呼び出し、$usces->itemsku[‘advance’] をechoすれば出力できます。
<?php
global $usces;
echo $usces->itemsku['advance'];
?>
*追記(2014/4/27 )
SKUの入力項目を複数追加したい
ここまできたらどうあっても複数の値を持たせたい。で、最初に思ったのは、inputを複数設置して配列にして渡せばええんちゃうん?ということで、これはやってみたものの、半分成功で半分失敗という結果に。保存や公開はできるのに、welcartの「更新」や「skuを追加する」ボタンによるajax処理では値が正しく受け渡されなかった。これに嵌ってかなり時間を費やした。
welcart本体に手を加えたく無いので、phpだけで実現するのはあきらめ、jQueryでいったん分割したinputをセパレータを挟んで一つの項目に戻すという邪道な手で処理することにしたのが以下。上記関数群の2番目と3番目のフィルターを下記に変更します。inputにclass名を付与し、次に読み込ませたCSSとjqueryで処理しています。値の数などは任意に変更できます。
CODE : Adding new multiple fields to SKUs on welcart
add_new_sku_meta_fieldとadd_new_sku_meta_row_advanceの関数を以下のように変更します。それ以外は、上記と同じです。
<?php
add_filter( 'usces_filter_sku_meta_form_advance_field', 'add_new_sku_meta_field'); //フィールドを新規追加
function add_new_sku_meta_field(){
?>
<script type="text/javascript">
jQuery.fn.splitfield = function(){
return this.each(function(){
if ( jQuery(this).is(":visible") ) { //オートセーブなどのときに重複処理しないように
var field = jQuery(this).hide(),
separator = "##", //好きなセパレータを設定
setval = field.val()?field.val().split(separator) : [],
input = [],
value = "",
splits = 3, //項目数に応じて設定
before = ["縦"," × 横"," × 高さ"], //個別に項目名が必要であれば設定
after = ["cm","cm","cm"]; //単位などが必要であれば自由に設定
for (var i = 0; i < splits; i++) {
value = (setval[i])?setval[i] : "";
input.push( '<p class="smallfield"><span>' + before[i] + '</span><input type="text" style="ime-mode:disabled;" onkeydown="return OnlyNumber(event)" value="' + value + '"/><span>' + after[i] + '</span></p>' );
} // 半角指定部(styleとonleydown)は削除可
var div = jQuery( "<div>" + input.join("") + "</div>" ).children().each( function(){
var values = [];
jQuery(this).children( "input" ).blur(function(){ //フォーカスアウト
jQuery(this).parent( "p" ).siblings().andSelf().each(function(){
values.push( jQuery(this).children( "input" ).val());
});
field.val(values.join(separator)); //各値をinput.spiltfield本体に代入
});
}).end();
field.after( div );
}
});
};
jQuery( ".splitfield", "#itemsku" ).splitfield();
jQuery( "#itemsku" ).ajaxSuccess(function() { // welcartのajax処理後、再splitする。
jQuery( "#newsku" ).find( ".splitfield" ).show().next().remove();
jQuery( "#itemsku" ).find( ".splitfield" ).splitfield();
});
</script>
<style type="text/css">
.item-sku-advance { padding:0;}
.item-sku-key { width: 30%; }
.item-sku-cprice { width: 16%; }
.item-sku-price { width: 20%; }
.item-sku-zaikonum { width: 16%; }
.item-sku-zaiko { width: 16%; }
#itemsku .smallfield { display:inline-block; margin:0 8px 0 2px; }
#itemsku .smallfield span { font-size:0.85em; }
#itemsku .smallfield:last-child { margin:0 0 0 2px; }
#itemsku .smallfield input { line-height:1em; width:40px; font-size:1em; }
</style>
<td colspan="2" class="item-sku-advance"><input name="newskuadvance" type="text" id="newskuadvance" class="newskuadvance metaboxfield splitfield" /></td>
<?php
}
add_filter( 'usces_filter_sku_meta_row_advance', 'add_new_sku_meta_row_advance',10,2); //フィールドを追加
function add_new_sku_meta_row_advance( $default_field, $sku ){
$metaname = 'itemsku[' .$sku["meta_id"]. '][skuadvance]';
return '<td colspan="2" class="item-sku-advance"><input name="' .$metaname.'" type="text" id="' .$metaname. '" class="newskuadvance metaboxfield splitfield" value="' .$sku["advance"]. '"/></td>'."n";
}
?>
ここではセパレータはダブルシャープ(##)にしてますが、何でも良いんで好きに変えて下さい。ただし、welcartはCSVでカンマ分割してるので、コンフリクトを避けるためにカンマは止した方が良いかもしれません。呼び出し方は以下の通り。[‘advance’]の値を取得しexplodeしています。値の数が2、3個だとループさせるほどでもないので、個別に呼び出せばいいと思います。例えばですが、こんな感じで。
<?php
$advance = $usces->itemsku['advance'];
if ($advance){
$adv = '';
$advance = explode( '##', $advance ); //セパレータで分割
if ( $advance[0] ){
$adv = '縦'.$advance[0].'cm';
}
if ( $advance[1] ){
if ($adv) $adv .= ' × ';
$adv .= '横'.$advance[1].'cm';
}
if ( $advance[2] ){
if ($adv) $adv .= ' × ';
$adv .= '高さ'.$advance[2].'cm';
}
echo '<p>このアイテムのサイズは【'.$adv.'】です。</p>';
}
?>
*追記(2015/9/01 )
カートページの商品名に追加項目の表記を反映する
質問があったので、カートの中で反映させる方法も書いておきます。tableの列を増やすには、wc_cart_page.phpやwc_confirm_page.phpの一部も書き換える必要があるので、ここでは簡単に商品名の下に表記することにします。advanceが複数の場合は上の表記を合わせてカスタマイズしてください。
/////////////////////// カートテーブルの変更 ///////////////////////
function my_usces_filter_cart_row( $row, $cart, $materials ){
global $usces;
$post_id = $materials['post_id'];
$cartItemName = esc_html( $materials['cartItemName'] );
$skus = $usces->get_skus( $post_id );
$advance = $skus[0]['advance'];
$row = str_replace( $cartItemName, $cartItemName.'<br/>'.$advance, $row);
return $row;
}
add_filter( 'usces_filter_cart_row', 'my_usces_filter_cart_row',10,3);
add_filter( 'usces_filter_confirm_row', 'my_usces_filter_cart_row',10,3);
はじめまして。
こちらの情報で新規にSKU入力項目を加えることが出来ました。
有難うございます。
そこで質問なのですが、上記の入力内容を商品マスターの一覧表に表示させたいのですが、ご教授いただけますでしょうか?
宜しくお願い致します。
order-list.php内にusces_filter_order_list_header と usces_filter_order_list_detail というフィルターがあるようです。
そちらで追加すれば何とかなりそうな気がします。
ちなみにこの記事の方法は公式拡張プラグインであるオートデリバリーとバッティングするため、あまりお奨めしておりません。(オートデリバリーを使わない場合、動作に問題はありませんが。)現在私は、sku_advanceの値を配列にしてストアする方法で運用しています。近日公開するつもりだったのですが、多忙のためなかなか時間が取れません。ご要望の内容も、そちらの記事を公開するときにあわせて検証・紹介したいと思います。
…書いてから気がついたのですが、order-listは受注リストで、商品マスターはusces_item_master_list.php ですね。
そして残念ながら都合のよいフックはパッと見なさそうなので、直書きするとか、かなり強引に修正するしかなさそうな気がします。何かよい方法を見つけたら逆に教えてください^^;
はじめまして。
こちらの記事を参考に、SKUに項目追加できました。
大変参考になる情報をありがとうございます!
追加項目に説明用ページのURLを入力しておりまして、
メンバーページ内の購入履歴で表示したいと考えています。
色々と触っておりますが、どうもうまく表示することができない状況です。
大変恐れ入りますが、ご教授いただけますでしょうか。
面倒なお願いで申し訳ありません。どうぞよろしくお願いいたします。
申し訳ありません。
以前質問された方↓を参考にしたところ、表示されました。
無駄にご連絡して申し訳ありません!
ありがとうございました。
はじめまして、sku項目追加の検索でここにたどりつきました。
希望とする記事だったので参考にさせていただいております。
記事通り「カスタム項目」を追加できましたが、カートに入れた時「カートの中」のページに、追加した「カスタム項目」の内容を表示する事ができません。
表示させるにはどのようにすればよいでしょうか?
PHP等勉強中でしてご教授いただければ幸いです。
よろしくお願いいたします。
追加
こちらで使用したのは上記「CODE : Adding a new field to SKUs of welcart」の内容のものです。
カートの中(確認画面・購入画面)で表示するには、usces_filter_confirm_rowおよびusces_filter_cart_rowというフィルターフックを使って、出力されるデータを置き換える必要があります。
welcartのtemplate_funcの該当箇所を見て、どの値が何に対応しているかさえ理解できればフィルターを作ることは難しくありません。動作や、安全性は保証し兼ねますが、以下参考コードを書いておきます。
返信ありがとうございます。
参考コードで表示できました。
追加したSKU項目を最終は注文時のメールにも反映させたいと思っています。template_funcを見て研究をしてみます。
親切な対応ありがとうございました。
注文メールに反映させるのは、該当フックがないので難しそうですね。
直接template_funcを触るか、でなければ、usces_admin_order_item_name_filterにフックしてgetCartItemName関数をすべて書き換えてしまって、処理中でis_singleとis_categoryとかだけ除外する、とかですかね。
おせになっております。
返信ありがとうございます。とても難しそうですね。
注文メールをどの部分で処理しているの解らず困っていました。
全体の構造、仕組みをもっと理解する必要がありそうです。
教えて頂いた部分を詳しく見てみたいとおもいます。
※まだ実装するかは決めていないのですが
【例】10000円以上で送料無料 の設定がありますが。
この送料無料設定を除外したい商品があるとします。
この場合、除外したい商品の編集画面で、カスタムフィールドを使い送料無料設定を除外する設定の様な、仕組みを作る事は可能でしょうか?
カスタマイズすれば可能だと思います。
ここが参考になりそうです。welcartカスタマイズブログ
http://welcustom.net/free-shipping-campaign/
このブログは現場目線で役立つ情報がたくさん載ってますので、welcartをお使いになる際は目を通されることをお勧めします。
おせわになっております。
良い情報ありがとうございます。
サイトを参考にカスタマイズがんばってみたいと思います。
また、よろしくお願いいたします。
はじめまして、大変興味深く拝読させていただき、見よう見まねでskuに項目を追加したのですが、メンバーページ内の購入履歴で追加した項目を表示させることができません。
functions内
template_func.php
を編集すれば実現するのかと思い、あれこれ試しましたが、どうにもお手上げの状況です。
ご教示いただけますと非常に助かります、どうぞよろしくお願いいたします。
template_func内だったら、2579行目から2631行目までのループ内で$advance = $cart_row[‘advance’];としたら呼び出せそうに見えます。
ただ、個人的にはusces_member_history 関数を直接弄るのはお奨めできません。プラグインの更新のときに面倒ですから。はなさんがどこにSKUを放り込みたいのか分からないのですが、ぱっと見た感じ、usces_filter_history_cart_headとusces_filter_history_cart_rowのフィルターでフックできそうに思います。
ただ、それらの関数を見てみると結構挿入しにくそうな作りになってますね。特にusces_filter_history_cart_rowの方。長々と再処理するか、いっそpreg_replaceで置き換えたほうが効率よさそうかな。フックを使うなら以下のような感じで。
以上すべて未検証です。
はなです、ご連絡ありがとうございます。
早速の御回答、まことにありがとうございます。
さっそく施策させていただきましたところ、商品の情報ではなく、購入した際の付随情報(購入の際に生じたポイントなど)の情報がでてきました。
例えば、現在の在庫状況(在庫あり:など)だけを追加できればと思っていたのですが、現在の商品の情報は取得できないのでしょうか。
勝ってばかりで申し訳ありませんが、 ご教示いただけますと非常に助かります、どうぞよろしくお願いいたします。
今ひとつ、どこに何を取得するのか分からないですが…
$post_id = $cart_row[‘post_id’];というのがあるので、以下のようにループを作成したら普通になんでも取得できるはずです。
勘で書いてます。未検証ですので誤表記に気をつけてください。
はなです。
ご教示いただきました通り、記述しても実現できませんでした。
そもそもと思い、最終的にfunctions内template_func.phpの
2628行あたりに
、
2628行あたりに
これだけで、購入履歴の商品名の前に”在庫あり”などの表示が出るかとおもいましたが何も表示できませんでした。
購入履歴では現在の商品の(SKU)情報が取得できないのかもわかりません。
どうしようもなく力量の問題だと思います。
基本からやり直さないとと猛省しております、お忙しい中、お手を煩わせ誠に申し訳ありません。
ただただ感謝の上、失礼いたします。
PS.今後も拝読させていただきます。
プラグイン内の関数を書き直すのは私のポリシーに反するのでfunctions.phpからフックで書き換える方法を書いておきます。
あとのカスタマイズはご自由にどうぞ。
私の管理サイトで導入して確認してみました。
はなです。
本当に、何を言えば良いやら言葉が見つかりません。
完璧に思い通りの表示をしてくれました。
(あとは文章などを追記する予定ですが)
正直、諦めていたところでしたので、本当に感謝の言葉しかありません。
今後、お手をわずらわすような作業はご依頼させていただきますのでよろしくお願いいたします。
本当にありがとうございました。
welcartでただ今悪戦苦闘しています。
phpとかcssについては、ほとんど知識がないに等しいので教えてください。
上記スクリプトをfunction.phpに書き加え、商品情報編集画面・sku欄に新たなフィールドを追加することができましたが、それが商品情報画面に反映されません。
下記作業をしてないからだろうと思われるのですが、対処の方法がどうしてもわかりません。
「商品情報ページのループ内でuscesを呼び出し、$usces->itemsku[‘advance’] をechoすれば出力できます。」とありますが、具体的にどのテンプレートのどの辺にその文言を書き加えれば良いのでしょうか?
商品の情報ページに表示させるだけであれば、wc_templates下のwc_item_single.php内に書き加えて下さい。
ここでは仮に【重さ】を表記したいとします。
wc_item_singleテンプレート内には、商品につきSKUが一つしかない場合(<!–1SKU–>以下)と、複数ある場合の2カ所(<!– some SKU–>以下)が存在していますので、両方を書き換える必要があります。global $usces;としてウェルカートのSKU情報を呼び出ししています。
変更箇所にコメントを入れてあります。デフォルトのテーマは使ってないのでちゃんと検証してないのですが、表示はしてくれるはずです。複数SKU(<!– some SKU–>以下)の場合、【単位】を動かしてテーブルに新規SKU項目を表示するためのスペースを作っています。デフォルトのテーマでない場合、ソースが違うかもしれませんが、基本的には同じはずなのであとは手探りで頑張って下さい!
ご丁寧な解説ありがとうございます。
あれこれ悩みながら、カスタムフィールドのカスタマイズでの対応も考えておりました。
またわからないことが出てきたら教えてください(汗)
どうもありがとうございました!