I'm trying to filter these collections without any change to the template, I had no problems with the up-sell (not tested), but the other two doesn't have an event.
Note: The dom structure is unknown
Up-sell
Event: catalog_product_upsell
public function checkUpsell(Varien_Event_Observer $observer){
if(!self::isModuleEnabled()){
return;
}
$upsell =$observer->getEvent()->getCollection();
$ids =array();
foreach($upsell as $item){
$ids[]=$item->getId();
}
$collection = Mage::getModel('country/product') ->getCollection()
->addAttributeToFilter('active', 1)
->addAttributeToFilter('product_id', array('in' => $ids));
if($collection->length >0){
$country = Mage::getSingleton('core/session')->getRazorphynCountry;
foreach($collection as $res){
if(($res->allowed==0 && strpos($countries, $country) !== false) || ($res->allowed==1 && strpos($countries, $country) === false)){
$upsell->removeItemByKey($res->product_id);
}
}
}
}
Configurable options
Note: Horrible, can cause eye-bleeding
Event: core_block_abstract_to_html_after
...
if( Mage::registry('current_product')->getTypeId()=='configurable'){ //to be checked
//Retrieve all options ids
$childIds = Mage::getModel('catalog/product_type_configurable')->getChildrenIds($productId);
//Retrieve rules to remove for all options
$collection = Mage::getModel('country/product')->getCollection()
->addFieldToFilter('active', 1)
->addFieldToFilter('product_id', $childIds)
->limit(count($childIds));
if($collection->length >0){
//Create an array with the items that will be removed
$removable=array();
foreach($collection as $res){
if(($res->allowed==0 && strpos($countries, $visitorCountry) !== false) || ($res->allowed==1 && strpos($countries, $visitorCountry) === false)){
$removable[$res->product_id]=true;
}
}
//Retrieve json with the product options (will be printed in the frontend
$json = Mage::createBlock('Mage_Catalog_Block_Product_View')->setProduct($productId)->getJsonConfig();
$arr=json_decode($json);
//I would like to print all the removed options
//each line is combination of removed options for the same product id
//label1: option - label2: option - label3:option
$removedOpt= array();
//Loop through options
foreach($arr['attribute'] as $element){
foreach($element['options'] as &$option){
foreach($option['products'] as &$productId){
if(in_array($productId,$removable)){
$removedOpt[$productId][]=$element['label'].': '.$option['label'];
unset($productId);
}
}
//Remove options if there is no associated product
if(count($option) == 0)
unset($option);
}
}
//Create final string with removed options
foreach($removedOpt as $o){
$o=implode(' - ',$o);
}
$removedOpt=implode("\n",$removedOpt);
$results = $xpath->query('//script');
foreach($results as $res){
//Ugh...ehm...replace the already printed json with the new one...
preg_replace('/new\s*Product\.Config\((.*)\)/',$json,$html);
}
Mage::getSingleton('core/session')->addNotice(Mage::helper('country')->__("The following options are not available in your country:")."\n".$removedOpt);
}
}
...
So my question are:
- is there a smart way to limit the configurable options?
- is there a way to achieve the same results for
cross-sells
andrelated product
?
config.xml:
...
<frontend>
<events>
<!-- Page Rendering event -->
<core_block_abstract_to_html_after>
<observers>
<razorphyn_country_core_block_abstract_to_html_after>
<type>singleton</type>
<class>Razorphyn_Country_Model_Observer</class>
<method>checkMerchantable</method>
</razorphyn_country_core_block_abstract_to_html_after>
</observers>
</core_block_abstract_to_html_after>
<!-- Remove up-sell items -->
<catalog_product_upsell>
<observers>
<razorphyn_country_catalog_product_upsell>
<type>singleton</type>
<class>Razorphyn_Country_Model_Observer</class>
<method>checkUpsell</method>
</razorphyn_country_catalog_product_upsell>
</observers>
</catalog_product_upsell>
</events>
...