残念ながら、すべてのサイトエンジンが製品の複数のタイプの価格を同時に提供するわけではありません。また、製品に複数の価格を設定できるエンジンでさえ、それらを切り替えるための柔軟なメカニズムを持たないことがよくあります。 後者は非常に人気のある「1C-Bitrix」です。 一方、この「CMS」バージョン(「ビジネス」エディション以上)に既に存在するこのCMSでは、いくつかのタイプの価格がサポートされています。一方で、特定の条件に応じてこれらの価格の動的切り替えを設定する方法は完全に不明です この部分の通常のマニュアルも、致命的な沈黙を保ちます。 Bitrixの仲間がこの迷惑な誤解を修正することを願っていますが、この幸せな瞬間を待たずに、明確な松葉杖の決定を思いつきました。実際にhabrasocietyと共有することにしました。
さあ行こう...
まず、 OnGetOptimalPriceハンドラーに注意する必要があります。 この関数はカーネルに長い間登場していたという事実にもかかわらず、その説明は最近オンライン文書に追加されました。 一方、このハンドラーは、特定の製品に最適な価格が自動的に選択されるとトリガーされ、その価格を再定義できます。 合計購入金額に応じて、バスケット内のすべての価格を再集計するために使用します。
ファイル/php_interface/init.phpでハンドラーを接続します(このファイルが存在しない場合、それを作成する必要があります-Bitrixは自動的に接続します)
AddEventHandler("catalog", "OnGetOptimalPrice", "MyGetOptimalPrice");
MyGetOptimalPrice関数の宣言と入力パラメーターは次のようになります。
function MyGetOptimalPrice($productID, $quantity = 1, $arUserGroups = array(), $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false)
上記のコードからわかるように、この関数は入力としてバスケット内の商品の合計金額を受け取りませんが、特定の製品のデータのみを受け取ります。 そのため、データベースにクエリを実行してバスケットデータを取得する必要があります。 なぜなら ハンドラーはバスケット内の製品の数に応じてサイクルで呼び出されるため、OnGetOptimalPriceハンドラーを最初に呼び出すときにバスケットのコンテンツの合計量を記録するグローバル変数を定義することは理にかなっています。
出力は次のようになります。
グローバル$ LocalPrice; $ LocalPrice = 0; 関数MyGetOptimalPrice($ productID、$ quantity = 1、$ arUserGroups = array()、$ renewal = "N"、$ arPrices = array()、$ siteID = false、$ arDiscountCoupons = false) { グローバル$ LocalPrice; if($ LocalPrice <= 0) { //現在のユーザーの現在のバスケットを取得します $ dbBasketItems = CSaleBasket :: GetList(false、 配列( "FUSER_ID" => CSaleBasket :: GetBasketUserID()、 「LID」=> SITE_ID、 「ORDER_ID」=>「NULL」 )、 偽 偽 配列(「ID」、「MODULE」、「PRODUCT_ID」、「CALLBACK_FUNC」、「QUANTITY」、「DELAY」、「CAN_BUY」、「PRICE」) ); while($ arItem = $ dbBasketItems-> Fetch()) { if($ arItem ['DELAY'] == 'N' && $ arItem ['CAN_BUY'] == 'Y') { $ LocalPrice + = $ arItem ['PRICE'] * $ arItem ['QUANTITY']; } } } //注文金額が最大10,000ルーブルのOPT 1 //注文量が最大20,000ルーブルのOPT 2 //注文量が20,000ルーブルを超えるOPT 3 //この製品で可能なすべてのタイプの価格を取得します $ arOptPrices = CCatalogProduct :: GetByIDEx($ productID); if($ LocalPrice <10000){ $価格= $ arOptPrices ['PRICES'] [1] ['PRICE']; $ catalog_group_id = 1; } elseif($ LocalPrice> = 10000および$ LocalPrice <20000){ $価格= $ arOptPrices ['PRICES'] [2] ['PRICE']; $ catalog_group_id = 2; } elseif($ LocalPrice> = 20000){ $価格= $ arOptPrices ['PRICES'] [3] ['PRICE']; $ catalog_group_id = 3; } 配列を返す( 'PRICE' =>配列( 「ID」=> $ productID、 'CATALOG_GROUP_ID' => $ catalog_group_id、 'PRICE' => $価格、 'CURRENCY' => "RUB"、 'ELEMENT_IBLOCK_ID' => $ productID、 'VAT_INCLUDED' => "Y"、 )、 '割引' =>配列( 'VALUE' => $割引、 'CURRENCY' => "RUB"、 )、 ); }
必要に応じて、キャッシュを追加して価格サンプルを保存し、条件のハードコード設定を取り除き、条件を構成ファイルまたはデータベースに転送することにより、コードを最適化できます。 原則として、バスケットからのデータの選択は、ハンドラー関数のスコープ外で行われ、セッションのどこかにスレッドの合計、Cookie、またはグローバル変数を格納することもできます(必要に応じて、正しいと見なされるように)。 もちろん、ケーススタディでは、これをすべて始めていませんでした。 健康に使用してください!