回答:
のオブザーバーを記述して、コレクションが関連製品コレクションである場合はcatalog_product_collection_load_after
、ロードされたコレクションに製品を追加できます。
use Mage_Catalog_Model_Product as Product;
use Mage_Catalog_Model_Product_Link as RelatedProduct;
use Mage_Catalog_Model_Resource_Product_Link_Product_Collection as RelatedProductCollection;
class IntegerNet_AutoRelated_Model_Observer
{
/**
* @see event catalog_product_collection_load_after
* @param Varien_Event_Observer $observer
* @throws Mage_Core_Exception
*/
public function addToRelatedCollection(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
if ($collection instanceof RelatedProductCollection
&& $collection->getLinkModel()->getLinkTypeId() === RelatedProduct::LINK_TYPE_RELATED
) {
$this->addItems($collection);
}
}
protected function addItems(RelatedProductCollection $collection)
{
/** @var Mage_Catalog_Model_Resource_Product_Collection $productsToAdd */
$productsToAdd = Mage::getResourceModel('catalog/product_collection');
$productsToAdd
->addStoreFilter()
->addIdFilter(array_diff([1,5,7,3], [$collection->getProduct()->getId()], $collection->getAllIds()))
->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->setPageSize($numberOfItems)
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addUrlRewrite();
foreach ($productsToAdd as $product) {
$collection->addItem($product);
}
}
}
->addIdFilter(array_diff([1,5,7,3], [$collection->getProduct()->getId()], $collection->getAllIds()))
これにより、商品[1,5,7,3]
が読み込まれますが、商品自体と、手動で関連商品として既に定義されている商品は除外されます。そうしないと、コレクションの重複が原因でエラーが発生します。これらのハードコードされたIDを構成に移動したい場合があります。
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addUrlRewrite();
これは、価格、製品リンク、および「製品リストで使用」として構成された属性を表示するために必要なデータをロードするための製品コレクションを準備しますが、それ以上は準備しません。
これは、view.phtmlのカテゴリIDによる製品リストの取得で説明されている私のAutoUpsellモジュールと非常によく似たソリューションです。コードのほとんどをそこから少し変更してコピーしました。
これは、カスタムオブザーバーメソッドを使用して行うことができます。そのためには、イベントでオブザーバーの関数を呼び出しますcatalog_product_save_after
。
これにより、管理パネルから商品を保存する際に、関連商品が割り当てられているかどうかを確認できます。
関連製品がない場合は、プログラムで関連製品を(製品IDで)割り当てることができます。
関連製品を割り当てる製品のIDが2で、関連IDが1、5、7、3であるとします。
次に:
$product = Mage::getModel('catalog/product')->load(2);
if($product)
{
$sRelatedIds = '1,5,7,3';
$aRelatedIds = explode(',', $sRelatedIds);
$aParams = array();
$nRelatedCounter = 1;
foreach($aRelatedIds as $id)
{
$aRelatedProduct = Mage::getModel('catalog/product')->load($id);
$aParams[$aRelatedProduct['entity_id']] = array('position' => $nRelatedCounter);
$nRelatedCounter++;
}
$product->setRelatedLinkData($aParams);
$product->save();
}
ご不明な点がございましたらお知らせください。
で新しいファイルを作成\app\code\local\Mage\Catalog\Block\Product\List\Related.php
してメソッドを探し、以下のコードに置き換えます。
protected function _prepareData()
{
$product = Mage::registry('product');
/* @var $product Mage_Catalog_Model_Product */
$this->_itemCollection = $product->getRelatedProductCollection()
->addAttributeToSelect('required_options')
->setPositionOrder()
->addStoreFilter();
foreach ($this->_itemCollection as $product) {
$productIds1[] = $product->getId(); // here we are getting the product ids of related products of current product.
}
$productIds = [1, 5, 7, 3]; // here you can set product id you want to show by default in all products.
$productscoll1 = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', ['in' => $productIds]);
$productscoll1->getSelect()->order("find_in_set(entity_id,'" . implode(',', $productIds) . "')");
$productscoll2 = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', ['in' => $productIds1]);
$productscoll2->getSelect()->order("find_in_set(entity_id,'" . implode(',', $productIds) . "')");
// print_r($productscoll1->getAllIds());
// print_r($productscoll2->getAllIds());
$merged_ids = array_merge($productscoll1->getAllIds(), $productscoll2->getAllIds()); // here we merge both collection ids.
// can sometimes use "getLoadedIds()" as well
//print_r($merged_ids);
//exit;
$this->_itemCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', ['in' => $merged_ids]);
// In this we set collection with default products merge with related products
if (Mage::helper('catalog')->isModuleEnabled('Mage_Checkout')) {
Mage::getResourceSingleton('checkout/cart')->addExcludeProductFilter($this->_itemCollection,
Mage::getSingleton('checkout/session')->getQuoteId()
);
$this->_addProductAttributesAndPrices($this->_itemCollection);
}
// Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
$this->_itemCollection->load();
foreach ($this->_itemCollection as $product) {
$product->setDoNotUseCategoryId(true);
}
return $this;
}
$ids = array_merge([1,3,5,7], $product->getRelatedProductCollection()->getAllIds());
単一のロードを実行すると改善される可能性がありますaddIdFilter($ids)
foreach ($this->_itemCollection
、IDの2つのクエリ:array_merge($productscoll1->getAllIds(), $productscoll2->getAllIds());
、2番目のロード:$this->_itemCollection->load();
です。上記の私の提案では、1つのIDクエリと1つのコレクションロードにそれを半分にします