News:

Support the VirtueMart project and become a member

Main Menu

BUG: Product Details Link Breaks Joomla SEF

Started by yagudaev, March 18, 2012, 23:12:21 PM

Previous topic - Next topic

yagudaev

Hi everyone,

I encountered a bug with the VMart and the Joomla SEF system and would like to share the problem as solution with you here. Spent about 2 days on trying to figure this one out.

Problem: when using Joomla SEF and having a link in the main menu of a site which houses Virtuemart. The link is called shop to have a url structure like http://www.example.comp/shop/. The link is set as a categories view and everything works fine until you drill down to an actual product. When clicking on a product instead of being directed to http://www.example.com/shop/category/product you are directed to http://www.example.com/component/virtuemart/category/product which is not what we want.

Solution: Links are created through the JRoute::_() method. When control is handed over by the Joomla router (includes/router.php) to the Virtuemart Router (components/com_virtuemart/router.php) is under the illusion that it is smarter than joomla at figuring out what menu item is currently active so it modifies the $query['Itemid'] without even checking if t is assigning something stupid to it, like 0. Which is exactly what it does. All I did below is check if the value of the menu item is set or not.

components/com_virtuemart/router.php lines 136-141 (only 1 line modified):
            if(!empty( $query['virtuemart_category_id'])){
$categoryRoute = $helper->getCategoryRoute($query['virtuemart_category_id']);
if ($categoryRoute->route) $segments[] = $categoryRoute->route;
if ($categoryRoute->itemId) $query['Itemid'] = $categoryRoute->itemId;
else if($jmenu['virtuemart']) $query['Itemid'] = $jmenu['virtuemart']; // PATCH: do not change Itemid if it changes it to '0'...
}


I do not understand why Virtuemart has to abuse arguments pass into it like that and why we need all that magic with scanning for menu items to begin with.

Finally, I have mentioned it before, but please migrate the source to github so we can help fix silly bugs like these!

Thanks,

Michael Yagudaev

waisign

Thanks for highlighting this. I'm having the same issue as well. Could u check whether I'm doing this right?

Code below:

case 'productdetails';
$virtuemart_product_id_exists = false;
if (isset($jmenu['virtuemart_product_id'][ $query['virtuemart_product_id'] ] ) ) {
$query['Itemid'] = $jmenu['virtuemart_product_id'][$query['virtuemart_product_id']];
} else {
if(isset($query['virtuemart_product_id'])) {
if ($helper->use_id) $segments[] = $query['virtuemart_product_id'];
$virtuemart_product_id_exists = true;
$virtuemart_product_id = $query['virtuemart_product_id'];
unset($query['virtuemart_product_id']);
}
if(empty( $query['virtuemart_category_id'])){
$query['virtuemart_category_id'] = $helper->getParentProductcategory($virtuemart_product_id);
}
if(!empty( $query['virtuemart_category_id'])){
$categoryRoute = $helper->getCategoryRoute($query['virtuemart_category_id']);
if ($categoryRoute->route) $segments[] = $categoryRoute->route;
if ($categoryRoute->itemId) $query['Itemid'] = $categoryRoute->itemId;
  else if($jmenu['virtuemart']) $query['Itemid'] = $jmenu['virtuemart']; // PATCH: do not change Itemid if it changes it to '0'...
} else {
$query['Itemid'] = $jmenu['virtuemart'][0] ;
unset($query['virtuemart_category_id']);
}
if($virtuemart_product_id_exists) {
$segments[] = $helper->getProductName($virtuemart_product_id);
}
}


many thanks

yagudaev

@waisign You just need to check $jmenu['virtuemart_product_id'] actually has a value assigned to it before modifying $query['Itemid'] which is how joomla decides what the SEF URL should be.

Another note is can Virtuemart actually implement this fix on the mainline pleas? Also can you please join us in the 21st century and use Git as the source control system on Github, so we can help fix these type of bugs by sending pull requests? All reputable open source projects are hosted on github. Even PHP recently moved there.