VirtueMart 3.8.8 10472(and before) in components/com_virtuemart/helpers/cart.php
THe line 943
$value = JComponentHelper::filterText($customData);
Remove all datas when you have an array of values
FOr eg :
customProductData[4074][228][115096][opt][0]: i6
customProductData[4074][228][115096][opt][1]: i0
customProductData[4074][228][115096][opt][2]: i0
customProductData[4074][228][115096][opt][3]: i1
Because only simple values are checked
($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id]
in this case customProductData[4074][228][115096][opt} is an array and is empty on save in the session !
Solution :
Use a recursive function to retrieve all values
private function checkAllValues ($datas){
foreach($datas as $i=>$customData){
if(is_array($customData)) {
$customData = $this->checkAllValues($customData);
} else {
$value = JComponentHelper::filterText($customData);
$value = (string)preg_replace('#on[a-z](.+?)\)#si','',$value);//replace start of script onclick() onload()...
$value = trim(str_replace('"', ' ', $value),"'") ;
$datas[$i] = (string)preg_replace('#^\'#si','',$value);
}
}
return $datas;
}
Modify the code
if(isset($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id])){
if(is_array($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id])){
foreach($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id] as $i=>$customData){
//$value = vmFilter::hl( $customData,array('deny_attribute'=>'*'));
//to strong
/* $value = preg_replace('@<[\/\!]*?[^<>]*?>@si','',$value);//remove all html tags */
//lets use instead
$value = JComponentHelper::filterText($customData);
$value = (string)preg_replace('#on[a-z](.+?)\)#si','',$value);//replace start of script onclick() onload()...
$value = trim(str_replace('"', ' ', $value),"'") ;
$customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id][$i] = (string)preg_replace('#^\'#si','',$value);
}
}
if(!isset($customProductDataTmp[$customfield->virtuemart_custom_id])) $customProductDataTmp[$customfield->virtuemart_custom_id] = array();
$customProductDataTmp[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id] = $customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id];
}
to
if(is_array($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id])){
$customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id] = $this->checkAllValues($customProductData[$customfield->virtuemart_custom_id][$customfield->virtuemart_customfield_id]);
}
Attached file with modification
Thank you for your work, Patrick. Do you think it is still valid for VM4? Please take a look, if you say yes, I am going to check your code. I worked on that the last year, so I wonder if it is still a problem.
Hi,
I do not know if it's solved today but the problem was in VirtueMart 3.8.8 10472
Sometime you need to create complex plugins and need to save it in 2 or 3 levels, so a recursive function should be used to be sure you never loose the datas.