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);
こんにちは。
いつも拝見しております。
上記ソースを参考に、function.phpとカテゴリーページ(category.php)に設置させて頂いた所、記事等の投稿ページのカテゴリーページが表示されなくなって(該当する項目は見つかりませんでした。という表記になって)しまいました。
回避する方法等はございますでしょうか?
自分が借りたコードに自分で責任を取れないならカスタマイズする前のソースに戻すべきでしょう。
あなたの言っていることは、「私の代わりに問題を解決してください(タダで、善意で)」と同じです。
記事主さんに対して非常に失礼です。