tips

welcartの商品を在庫や価格で絞り込み&並べ替えする。

welcart sort product

アーカイブページのループに在庫や価格でのソート・絞り込みを反映させる。

在庫がないのに商品が表示されているのは楽●の空売りみたいで鬱陶しい。商品数が多ければなおのこと。ところが、通常のqueryにwelcartの在庫を 反映させることはできません。一旦ループから離脱して再ループさせれば擬似的に実現できるが、ページ送りやレイアウト崩れの可能性を考えるとテンプレート ごとに細かな対応が必要で面倒臭い。

で、困った時のウェルカスタムさんで探したところ「queryに在庫情報を組み込む現実的な解決法」が掲載されていた。ここによく纏められているように、在庫状態ではなく在庫数で判別しているので縛りがあること、また、複数SKUを持つ商品の場合の処理など、ウェルカートのSKUがシリアライズされているので、価格でのソートなども含めてクエリでの絞り込みの実現は難しそうだ。

ということで、現状はカスタムフィールドにデータを持たせるのが唯一の解決策と思われたので、最終的に以下のようにカスタマイズすることにしました。

各商品記事のカスタムフィールドに必要な情報を書き込む処理

ソートすることを目的にするなら、独立したカスタムフィールドにクエリから参照しやすように数値で登録されていることがベストでしょう。

まずは、以下のようにsave_postにフックしてにソート用のカスタムフィールドを書き込むことにしました。ついでに usces_action_reg_orderdataという受注確定後に処理されるフックがあったので、それにも引っ掛けることにする。 usces_have_skus()はループ内で複数回使うとだめだったりと、扱いが難しいので、get_skusでpostIDからskuのデータ をすべて取得、直接在庫の有無を呼び出す方法を採用、skuを複数展開されていても大丈夫なように、ステータスを一旦配列に入れてから最小の値だけ取り出 すことにします。これで、在庫がなくなったら反映されるという基本要件を満たしてくれます。ちなみに最後のcurrent_screenへのフックはというと、商品マスターの「最新の情報に更新」ボタンを押すとすべての商品データのカスタムフィールドを設定してくれる、という我ながらなんという親切設計!!

###0###

welcartにはget_bestseller_idsという関数があったので、当初は「人気順」もダイレクトにベストセラーの順位を登録するように設計してみました。しかしショップサイトの問題点として、「価格」や「在庫」が絶対的な情報であるのに対して、商品の「人気順」が相対的な数値ということがあります。つまり1点売り上げがあるとすべての順位に変動が生じてしまうので、一々すべての商品のカスタムフィールドを更新しなくてはならなくなり、延いてはユーザーサイドの表示速度に影響が出る可能性もあります。wp_cronなどを用いて定期更新にする手も考えましたが、それでも二段階更新になることには変わりないので、人気順の代わりにbestseller_idsも参照している1ヶ月の「売上数」をカウントしてカスタムフィールドに登録することにしました。これならば、売上があった際に該当商品を変更するだけで済みます。(とはいえ、在庫数の変動や記事の更新時にカウントされているので、しばらく売上がない商品は更新されないので完全とは言えない。厳密さを求める向きは手動反映かcronの設置をどうぞ。)

アーカイブページ内での商品一覧のソート処理

ループ全般にフックしてくれるpre_get_postという便利な関数を使用します。$_GET[‘instock’]で在庫の有無を、$_GET[‘sort’]で並び順を変更するという仕様。デフォルトで在庫がないものは通常ループ内で非表示に設定してあります。

つまり、セレクトボックスなどで、カテゴリページのリンクに以下の様に絞り込み用のクエリを設定してやれば、ループが自動的に読み込まれるわけです。例としては以下のようになります。

価格の安い順:
//www.example.com/category/item?sort=price_desc

価格の高い順:
//www.example.com/category/item?sort=price_asc

価格高い順、かつ在庫のない商品もすべて表示:
//www.example.com/category/item?sort=price_asc&instock=false

 

###1###

言わずもがなですが、在庫がない場合 if ( $instock !== ‘false’ ) のところを if ( $instock === ‘true’ ) とかにしてやれば、trueが設定されている時に「在庫あり」のみを表示(在庫なしは表示しない)というように反転できます。

paginate_linksはその名の通りページネーションやカテゴリのリンク出力にフックしてくれるフィルターで、ページを送ったらソートが解除されると困るので設定してあります。term_linkはカテゴリを選択していってもクエリを継続させます。絞り込み系のサイト構成に向いています。入らなければコメントアウトしましょう。

 

リンクの実際の出力方法など

並べ替えボタンの出力例も書いておきます。

###2###
###3###

Your Comment

コードの記述は<pre>または<code>タグで括って下さい。自動的にエスケープされます。

 

右の文字を入力して下さい captcha

1 comment

  1. 匿名

    Jan 12, 2018

    こんにちは。いつも拝見しております。

    上記ソースを参考に、function.phpとカテゴリーページ(category.php)に設置させて頂いた所、記事等の投稿ページのカテゴリーページが表示されなくなって(該当する項目は見つかりませんでした。という表記になって)しまいました。
    回避する方法等はございますでしょうか?

    返信する