Hi, i post my little hack (sorry for my english...) , i used joomla 2.5.1 and latest virtuemart 2.0.2. I need to display related downloadable files of a product , but normal view show all media files. So i have changed VM for my needs.
First i have read this post: http://forum.virtuemart.net/index.php?topic=93337.0 (http://forum.virtuemart.net/index.php?topic=93337.0) and the procedure to attach files to a product (thanks jenkinhill):
- Uploaded via ftp the pdf files into the product media directory - joomla_root/images/stories/virtuemart/product (you could use Joomla's media uploader for this, but ftp is quick for multiple files)
- Open VirtueMart Shop/Media File list - and Synchronize media to VirtueMart
- Open VirtueMart Shop/Media File list - and Synchronize media to VirtueMart
- Still in the media list edit each of the files and make them downloadable, enter a suitable title to be displayed (Displayed image title) and I also enter the "Used thumb url" for a 50x50 pdf icon I have uploaded to use rather than the default larger icon.
- Open a product, go to the Custom Fields tab and create a Custom Field Type - Photo (even though it is a pdf file), select the file from the dropdown list and save.
i have changed the point 4: i created a Custom Field cloned by Photo and changed with title PDF and same way for ZIP (just for my mental order!)
Now the hack! (a premise: we have two way for resolve the problem, change the native functions or created other, in this example i create new functions.)
Change the model files:first open file administrator/components/com_virtuemart/models/customfields.php and find the function getProductCustomsField, clone this function and change the name in getProductCustomsFieldDownloadable.
The native function make a LEFT join with #__virtuemart_customs and #__virtuemart_product_customfields, but in my function make another join with #__virtuemart_medias, because in this table i found file_title, file_description, and file_is_downloadable, this values are the title and the description for file and i not found in the other two tables.
the new function is:
/**
* AUthor Francesco Reitano
* Load all custom fields for a Single product downlodable
* return custom fields value and definition
*/
public function getProductCustomsFieldDownloadable($product) {
$query='SELECT C.`virtuemart_custom_id` , `custom_element`, `custom_params`, `custom_parent_id` , `admin_only` , `custom_title` , `custom_tip` , C.`custom_value` AS value, `custom_field_desc` , `field_type` , `is_list` , `is_hidden`, `layout_pos`, C.`published` , field.`virtuemart_customfield_id` , field.`custom_value`, field.`custom_param`, field.`custom_price`, field.`ordering`, media.`file_title`, media.`file_description`, media.`file_is_downloadable`
FROM `#__virtuemart_customs` AS C
LEFT JOIN `#__virtuemart_product_customfields` AS field ON C.`virtuemart_custom_id` = field.`virtuemart_custom_id`
LEFT JOIN `#__virtuemart_medias` AS media ON field.`custom_value` = media.`virtuemart_media_id`
Where `virtuemart_product_id` ='.(int)$product->virtuemart_product_id.' and `field_type` != "G" and `field_type` != "R" and `field_type` != "Z"';
$query .=' AND is_cart_attribute = 0 AND media.`file_is_downloadable` = 1 order by field.`ordering`,virtuemart_custom_id' ;
$this->_db->setQuery($query);
if ($productCustoms = $this->_db->loadObjectList()) {
$row= 0 ;
if(!class_exists('vmCustomPlugin')) require(JPATH_VM_PLUGINS.DS.'vmcustomplugin.php');
foreach ($productCustoms as $field ) {
if ($field->field_type == "E"){
$field->display ='';
JPluginHelper::importPlugin('vmcustom');
$dispatcher = JDispatcher::getInstance();
$ret = $dispatcher->trigger('plgVmOnDisplayProductFE',array($product,&$row,&$field));
}
else {
$field->display = $this->displayType($field->custom_value,$field->field_type,$field->is_list,$field->custom_price,$row,0,$field->virtuemart_custom_id);
}
$row++ ;
}
return $productCustoms;
} else return array();
}
ok, open file administrator/components/com_virtuemart/models/products.php and find the row:
$product->customfields = $customfields->getProductCustomsField($product);
after write this:
$product->customfieldsdownloadable = $customfields->getProductCustomsFieldDownloadable($product);
Change the viewopen file components/com_virtuemart/views/productdetails/view.html.php and find:
if(!empty($product->customfields )){
foreach($product->customfields as $k =>$custom){
if(!empty($custom->layout_pos)){
$product->customfieldsSorted[$custom->layout_pos][] = $custom;
unset($product->customfields[$k]);
}
}
$product->customfieldsSorted['normal'] = $product->customfields;
unset($product->customfields);
}
after write:
if(!empty($product->customfieldsdownloadable )){
foreach($product->customfieldsdownloadable as $k =>$customd){
if(!empty($customd->layout_pos)){
$product->customfieldsdownloadableSorted[$customd->layout_pos][] = $customd;
unset($product->customfieldsdownloadable[$k]);
}
}
$product->customfieldsdownloadableSorted['normal'] = $product->customfieldsdownloadable;
unset($product->customfieldsdownloadable);
}
ok the last modify to view the result, open components/com_virtuemart/views/productdetails/tmpl/default_customfields.php and change:
foreach ($this->product->customfieldsSorted[$this->position] as $field) {
in
foreach ($this->product->customfieldsdownloadableSorted[$this->position] as $field){
now in the array we have just downloadable files and in $field->file_title and $field->file_description the title and the description for file!
thanks
we can change this hack modify the native function getproductCustomslist, but you need to change the query in :
$query='SELECT C.`virtuemart_custom_id` , `custom_element`, `custom_params`, `custom_parent_id` , `admin_only` , `custom_title` , `custom_tip` , C.`custom_value` AS value, `custom_field_desc` , `field_type` , `is_list` , `is_hidden`, `layout_pos`, C.`published` , field.`virtuemart_customfield_id` , field.`custom_value`, field.`custom_param`, field.`custom_price`, field.`ordering`, media.`file_title`, media.`file_description`, media.`file_is_downloadable`
FROM `#__virtuemart_customs` AS C
LEFT JOIN `#__virtuemart_product_customfields` AS field ON C.`virtuemart_custom_id` = field.`virtuemart_custom_id`
LEFT JOIN `#__virtuemart_medias` AS media ON field.`custom_value` = media.`virtuemart_media_id`
Where `virtuemart_product_id` ='.(int)$product->virtuemart_product_id.' and `field_type` != "G" and `field_type` != "R" and `field_type` != "Z"';
$query .=' AND is_cart_attribute = 0 order by field.`ordering`,virtuemart_custom_id' ;
without the condition AND media.`file_is_downloadable` = 1, so i have all the files, and in the view i can filter with file_is_downloadable variable, this is best for the performance (i make just one query)
No need to hack
http://forum.virtuemart.net/index.php?topic=99225.msg327903#msg327903
questions:
1) i need use media files uploaded, if my custom fileds is not image type but string i don't have a list of media files, if a use string how i can link media file and product? (with copy and paste url is not a best practice for me)
2) i wont use `file_title`, `file_description`, `file_is_downloadable`from #__virtuemart_medias, with this method i have?
thanks