Magento 1で製品のタイプを変更するには、*コンテンツマネージャーは、新しい製品を手動で作成するか、元の製品のコピーを作成するか、開発者にコードを介してこれを行うよう依頼する必要があります。 Magento 2. *は、この目標を達成するための新しい「機能」を導入しています。 対処する前に(「自動変換」と呼びます)、正しい結果を得るためにいくつかの点に留意する必要があります。
ユーザーの観点からの自動変換
管理パネル、またはコンテンツマネージャーの観点からの動作を見てみましょう。 前と同様に、作成する前に新しい製品のタイプを選択できます。
Magento 1では、これは[製品の追加]をクリックした後、[管理]> [カタログ]> [製品の管理]>ページに表示され、製品のセットとタイプの属性を選択します。
Magento 2では、このために、[管理]> [製品]> [カタログ]ページで、[製品の追加]ボタンの右側にある矢印をクリックします。
必要なタイプを選択すると、Magentoは、定義済みのオプションや選択したタイプの新しいセクションを含む新しい製品の編集ページを表示します。 シンプル製品の製品タイプを選択するか、「製品の追加」をクリックするだけで、シンプル製品の編集ページが表示されますが、次の3つのことに注意してください。
- 重み属性
- セクション構成
- ダウンロード可能な情報セクション
これら3つのセクションは、製品のタイプを決定します。
Magento 2は、次の製品の新規製品と既存製品の両方の製品タイプを(保存時に)自動的に変更できます。
このために何をする必要があるかを検討してください。
シンプルな仮想製品
重量を設定した場合、「重量」=「アイテムには重量がありません」(正確には重量がなく、入力フィールドから値を削除するだけではありません)、製品は仮想製品として保存されますが、製品編集ページに戻り、製品には重量があるため、保存するとすぐにシンプル製品に変換されます。
ダウンロード可能な製品
シンプルな製品をダウンロード可能にするには、「重量」=「アイテムに重量がありません」を設定し、以下の「ダウンロード可能な情報」セクションに1つ以上のリンクを追加する必要があります。 この製品をシンプルな製品に戻すには、「重量」=「アイテムに重量があります」と設定して、製品を保存します。
構成可能な製品
Simple製品をConfigurableに変えるには、上記のように任意の補助製品を追加します。 そして、再びシンプルにするには、すべての構成を削除して、[保存]をクリックします。 既に理解しているように、これは、Magento 2には(Magento 1のように)子なしでは構成可能な製品が存在できないことを意味します。
それだけです。
ご注意
構成可能製品への自動変換を使用する前に、Magento 2では構成可能製品から価格を取得する原則が変更されていることに留意する必要があります。 Magento 1 Configurableでは、製品には独自の価格があり、関連製品の価格は完全に無視されていました。 Magento 2は異なるアプローチを採用しています。 現在、構成可能な製品は、接続された子から計算された価格を使用します。 コインの裏側は、すべての付属製品を削除すると、その製品は単純な製品に変換されますが、管理パネルのグリッドページからそれに関連付けられているすべての製品を削除しても、製品は変換されないということです(その理由は後述します)。 新しいロジックを考えると、製品は子がある場合にのみ構成可能です。そうでない場合は、単純な製品に「変換」されます。これにより、特に商品の輸入で作業している場合、コードに予期しないエラーが発生する可能性があります
* Magento 2.1では、これらのエラーの一部が修正され、$ product-> getFinalPrice()メソッドを直接呼び出すと、例外がスローされるようになりました
Fatal error: Uncaught exception 'Magento\Framework\Exception\LocalizedException' with message 'Configurable product "…sku…" does not have sub-products' in vendor\magento\module-configurable-product\Pricing\Price\ConfigurablePriceResolver.php:52
開発者向け
次に、すべてが正確に機能する仕組みについて説明します。 最も重要なことから始めたいと思います。クラスMagento \ Catalog \ Model \ Product \ TypeTransitionManagerです。
... public function __construct( \Magento\Catalog\Model\Product\Edit\WeightResolver $weightResolver, array $compatibleTypes ) { $this->compatibleTypes = $compatibleTypes; $this->weightResolver = $weightResolver; } public function processProduct(Product $product) { if (in_array($product->getTypeId(), $this->compatibleTypes)) { $product->setTypeInstance(null); $productTypeId = $this->weightResolver->resolveProductHasWeight($product) ? Type::TYPE_SIMPLE : Type::TYPE_VIRTUAL; $product->setTypeId($productTypeId); } } ...
これは、2つのメソッド__constructとprocessProductを持つかなり単純なクラスです。 すべての魔法は、2番目のメソッドprocessProduct($ product)にあります。 ご覧のとおり、転送された製品のタイプが互換性のあるタイプの配列にあるかどうかをチェックし、製品に重量がある場合はシンプル製品、そうでない場合は仮想製品です。
Magento 2.1で。 ご想像のとおり、次のタイプは互換性があります。
- シンプル
- バーチャル
- ダウンロード可能
- 構成可能
それらはすべてdi.xmlを介して送信されます
... <type name="Magento\Catalog\Model\Product\TypeTransitionManager"> <arguments> <argument name="compatibleTypes" xsi:type="array"> <item name="simple" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_SIMPLE</item> <item name="virtual" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL</item> </argument> </arguments> </type> ...
つまり、これらのタイプのみがシンプル製品または仮想製品に変換できます。
前述のように、Simple製品は、同じ方法で構成可能なダウンロード可能な製品に変換できます。 次のクラス(プラグイン)のすべての魔法:
- Magento \ダウンロード可能\モデル\製品\ TypeTransitionManager \プラグイン\ダウンロード可能
- Magento \ ConfigurableProduct \ Model \ Product \ TypeTransitionManager \ Plugin \ Configurable
Magento \ Downloadable \ Model \ Product \ TypeTransitionManager \ Plugin \ Downloadable :: aroundProcessProduct()は、製品タイプがSimple、Virtual、Downloadableであり、ダウンロード可能なキーを持つデータがフロントエンドから送信され、この製品に重量がないことを確認します。 その場合、それはダウンロード可能です。
... public function aroundProcessProduct( \Magento\Catalog\Model\Product\TypeTransitionManager $subject, Closure $proceed, \Magento\Catalog\Model\Product $product ) { $isTypeCompatible = in_array( $product->getTypeId(), [ \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE, \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL, \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE ] ); $downloadableData = $this->request->getPost('downloadable'); $hasDownloadableData = false; if (isset($downloadableData)) { foreach ($downloadableData as $data) { foreach ($data as $rowData) { if (empty($rowData['is_delete'])) { $hasDownloadableData = true; break 2; } } } } if ($isTypeCompatible && $hasDownloadableData && !$this->weightResolver->resolveProductHasWeight($product)) { $product->setTypeId(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE); return; } $proceed($product); } ...
Magento \ ConfigurableProduct \ Model \ Product \ TypeTransitionManager \ Plugin \ Configurable :: aroundProcessProduct()リクエストに「attributes」キーを持つデータが含まれている場合、プラグインは製品タイプを「設定可能」に変更します。
... public function aroundProcessProduct( \Magento\Catalog\Model\Product\TypeTransitionManager $subject, Closure $proceed, \Magento\Catalog\Model\Product $product ) { $attributes = $this->request->getParam('attributes'); if (!empty($attributes)) { $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE); return; } $proceed($product); } ...
すべての仕組み
上記のように管理パネルから製品を保存しようとすると、このコードのおかげで製品のタイプが上記の1に変更されますが、save()メソッドを使用して製品モデルを保存しようとしても、何も変わりません。 ポイントは、商品の保管を処理するコントローラーです。
Magento \ Catalog \ Controller \ Adminhtml \ Product \ Save :: execute()は、 Magento \ Catalog \ Model \ Product \ TypeTransitionManagerクラスのインスタンスを使用します
... $product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest())); $this->productTypeManager->processProduct($product); … $product->save(); ...
ご覧のとおり、製品の変換はsave()メソッドに関連付けられておらず、製品を作成する直前に呼び出されます。
結論の代わりに
ユーザーおよび開発者にとって、Magento 2の新機能がどのように機能するかが少し明確になったと思います。Magento2の存在全体について、どこにも書かれていないことに驚かされます。
また、Magento 2では、新しい種類の商品を追加するのは非常に簡単です。ユーザーが商品を相互に変換できるようにする必要がある場合は、モジュールのdi.xmlに数行を追加して独自のプラグインを作成するだけです。