welcart:価格検索(絞り込み)機能を作成する
Tag: Welcart
welcartには価格検索機能がありません。
データベースの構造上無理なんですが、ある程度条件を絞ると機能追加も比較的容易なのでやってみました。。
wordpress上のプラグインはカスタマイズするにしてもやりやすくて楽しいです。
EC-CUBEも何度か触ったことありますが突っ込んだカスタマイズするには敷居が高そうでした。
welcartで価格検索できない理由
welcartで価格検索できない理由はデータベースの構造にあります。
商品データである商品名や商品コード等はいいんですが、価格が設定されてあるSKU情報が一つのカスタムフィールドにまとめて入っています。
こんなSKU情報↑が_isku_というカスタムフィールドにこんなかたち↓で保管されています。
a:9:{s:4:"code";s:6:"item01";s:4:"name";s:0:"";s:6:"cprice";s:4:"5000";s:5:"price";s:4:"4000";s:4:"unit";s:0:"";s:8:"stocknum";s:2:"10";s:5:"stock";s:1:"0";s:2:"gp";s:1:"0";s:4:"sort";s:1:"0";}
これみたらできないのわかりますよねー。
EC-CUBEだとwelcartのSKUにあたる部分が独立したデーブルにあり、各フィールドに分割して保存されているので検索が可能なわけです。
価格検索を追加する際の考え方
やり方は簡単で、検索用のカスタムフィールドを作成しそれに価格をセットするだけ。
それを元に検索をかけるというやり方です。
最初にある程度条件を絞ればと書きましたがその条件を書いていきます。
- 検索用価格情報は各商品につき1つ
- 複数SKUがあっても価格は全て同じ場合
- 複数SKUがあり価格が違う場合は一番最初のSKU販売価格
検索用のカスタムフィールドへ商品追加更新時に上記の条件で都度検索用価格をセットします。
複数SKUで価格もバラバラの場合でも作り方によっては対応も可能だと思いますが、ちょっと面倒なのと表示させる部分にもちょっと改良がいるかなと思い見送りました。
カスタムフィールドをセットする
カスタムフィールド名は「search_price」とします。
別になんでもいいんですがわかりやすいかなと。
商品追加更新
通常の商品追加更新事にカスタムフィールをを更新します。
以下をfunctions.phpに追加してください。
function set_search_price( $post_id, $post ) { if( get_post_meta( $post_id, '_itemCode', true ) ) { $price = usces_the_firstPrice( 'return', $post ); update_post_meta( $post_id, 'search_price', $price ); } } add_action( 'save_post', 'set_search_price', 99, 2 );
フックsave_postを使用します。
引数$post_idと$postを使用するので最後の数字が2になってます。
まずカスタムフィールド「_itemCode」を取得し、これで商品情報かどうかを判別しています。
次にwelcartの関数usces_the_firstPriceで1番目のSKUにある販売価格情報を取得します。
この関数の引数は記事IDではなくて記事オブジェクトなんですよね。なのでフックの引数に$postを設定しています。
最後にupdate_post_metaでカスタムフィールド「search_price」に先程取得した価格をセットして終了。
商品情報更新した後にカスタムフィールド欄でちゃんとセットされてるか確認してください。
CSVで一括登録時
厄介なのがCSVで一括登録した際の更新です。
普通にsave_postでいけるのかなと思ってたらCSVでの更新時はデータベースを直接更新してました。
なので場所探しにちょっと苦労しましたがうまくいけたっぽい。
以下をfunctions.phpに追加してください。
function set_search_price_csv( $post_id, $datas, $add_field_num ) { if( $datas ) { $price = $datas[30 + $add_field_num]; update_post_meta( $post_id, 'search_price', $price ); } } add_action( 'usces_action_uploadcsv_itemvalue', 'set_search_price_csv', 99, 3 );
welcartのフックusces_action_uploadcsv_itemvalueを使用します。
これはプログラムファイルのdefine_function.phpに書かれているので興味があれば探してみてみてください。
引数は3つ使用します。
詳しい説明はちょっと省きますが、$datasにはその商品の1つ目のSKU情報が入っており、CSVの並びににおける30+$add_field_num番目が販売価格情報になります。
セットは商品追加更新時と同じupdate_post_metaで行います。
CSVをエクスポートするとカスタムフィールドの項目も含まれますが、そこは変更無しでOK!変更したとしても上記処理で上書きされると思います。
価格絞り込み機能の実装
一覧はカテゴリー「item」のページです。
全商品の中から指定した価格にマッチングした商品のみを表示させます。
絞り込み選択部分
下限をmin_price、上限をmax_priceで指定し、リンク形式の場合はパラメータ付きURLで、フォーム形式の場合はGETで情報を飛ばします。
下記のソースをテンプレートに書くかウィジェットに追加するかしてください。
リンク形式
<ul> <li><a href="<?php echo esc_url( home_url( '/category/item/' ) ); ?>?min_price=0&max_price=4999">~4999</a></li> <li><a href="<?php echo esc_url( home_url( '/category/item/' ) ); ?>?min_price=5000&max_price=9999">5000~9999</a></li> <li><a href="<?php echo esc_url( home_url( '/category/item/' ) ); ?>?min_price=10000&max_price=14999">10000~14999</a></li> </ul>
フォーム形式
<form action="<?php echo esc_url( home_url( '/category/item/' ) ); ?>" merhod="get"> <input type="text" name="min_price" size="2"> ~ <input type="text" name="max_price" size="2"> <button>検索</button> </form>
フォームの場合、typeをnumberにしたりjsで数字のチェック入れたりしたほうがいいかも。
カテゴリページのクエリを書き換えて価格絞り込みを反映させた一覧を取得
カテゴリページで一覧を表示する前にクエリを書き換えて価格絞り込みを反映させます。
この場合はフック「pre_get_posts」を使用します。
このフックはクエリ変数オブジェクトの生成後、実際にクエリが実行される前に呼び出されます。
以下をfunctions.phpに追加してください。
function custom_item_query( $query ) { if ( is_admin() || !$query->is_main_query() ){ return; } if( !$query->is_category() || !usces_is_cat_of_item( get_category_by_slug( $query->query['category_name'] )->term_id ) ) { return; } if( isset( $_GET['min_price'] ) || isset( $_GET['max_price'] ) ) { $min = ( isset( $_GET['min_price'] ) && $_GET['min_price'] ) ? intval( $_GET['min_price'] ) : 0; $max = ( isset( $_GET['max_price'] ) && $_GET['max_price'] ) ? intval( $_GET['max_price'] ) : 9999999; $meta_query[] = array( 'key' => 'search_price', 'value' => array( $min, $max ), 'compare' => 'BETWEEN', 'type' => 'NUMBER' ); $query->set( 'meta_query', $meta_query ); } } add_action('pre_get_posts','custom_item_query');
- 管理画面かメインクエリじゃない場合は何もしません。
- カテゴリページじゃないか商品一覧ページじゃない場合は何もしません。
- urlパラメータ「min_price」「max_price」どちらか1つでも設定されている場合はクエリの書き換えを行います。
usces_is_cat_of_itemはwelcartの関数で商品カテゴリかどうかを調べる関数です。
引数はカテゴリIDなのですが、この段階だとカテゴリIDが情報としてなかったためカテゴリスラッグから取得します。
urlパラメータ「min_price」「max_price」をそれぞれ$min,$maxという変数に格納しmeta_query用のクエリを作成ます。
compare => BETWEENはvalueの$min~$maxまでの間という意味です。
なので下限が5000円、上限が9999円だった場合、カスタムフィールドsearch_priceに入っている数字が5000から9999までの間のものを取得しろという意味になります。
$query->set()でもともとあるクエリに作成したmeta_query用のクエリを追加します。
以上で価格検索機能の完成です。
多分大丈夫だと思うんですけど、数個の商品しか登録してない状態でしか試してないのでなにか問題あったらコメントください。
次はwelcartにある「複合検索」に価格検索を追加してみようかと思ってます。