One of the things that the ps_session->url() function does is to search the menu table for an entry that matches the set of parameters for a url so that the correct value for Itemid can be assigned. There are 2 problems with the way it works.
1 The queries use ambiguous selection criteria. "like 'category_id=1' would match any value that starts with 1, i.e. 1, 10, 11 etc.
2 The logic uses a cascade so that if a product_id is present but doesn't find a match (almost always the case, who has menu items for individual products?) the program then tries to match the category_id. If both values are present, the category menu entry is matched with a product - clearly wrong.
In my system I fixed this by replacing ps_session lines 513 to 544 (build 1760)
// Check if there is a menuitem for a product_id (highest priority)
if (!empty($ii_arr['product_id'])) {
if ($ii_product_id=intval($ii_arr['product_id'])) {
$db->query( "SELECT id FROM #__menu WHERE link='index.php?option=com_virtuemart' AND params like '%product_id=$ii_product_id%' AND published=1");
if( $db->next_record() ) $tmp_Itemid = $db->f("id");
}
}
// Check if there is a menuitem for a category_id
// This only checks for the exact category ID, it might be good to check for parents also. But at the moment, this would produce a lot of queries
if (!empty($ii_arr['category_id'])) {
$ii_cat_id=intval($ii_arr['category_id']);
if ( $ii_cat_id && $tmp_Itemid=='') {
$db->query( "SELECT id FROM #__menu WHERE link='index.php?option=com_virtuemart' AND params like '%category_id=$ii_cat_id%' AND published=1");
if( $db->next_record() ) $tmp_Itemid = $db->f("id");
}
}
// Check if there is a menuitem for a flypage
if (!empty($ii_arr['flypage'])) {
$ii_flypage=$db->getEscaped(vmget($ii_arr,'flypage'));
if ($ii_flypage && $tmp_Itemid=='') {
$db->query( "SELECT id FROM #__menu WHERE link='index.php?option=com_virtuemart' AND params like '%flypage=$ii_flypage%' AND published=1");
if( $db->next_record() ) $tmp_Itemid = $db->f("id");
}
}
// Check if there is a menuitem for a page
if (!empty($ii_arr['page'])) {
$ii_page=$db->getEscaped(vmget($ii_arr,'page' ));
if ($ii_page && $tmp_Itemid=='') {
$db->query( "SELECT id FROM #__menu WHERE link='index.php?option=com_virtuemart' AND params like '%page=$ii_page%' AND published=1");
if( $db->next_record() ) $tmp_Itemid = $db->f("id");
}
}
with
// Check for a matching menu item
if( $ii_arr['product_id'] ) { // Product page
$ii_product_id = (int)$ii_arr['product_id'];
$ii_cat_id = (int)$ii_arr['category_id'];
$ii_cat_id_required = false;
$ii_page = 'shop.product_details';
$ii_page_required = false;
if( $ii_arr['page'] ) {
$ii_page = $db->getEscaped( vmget($ii_arr, 'page') );
if( $ii_page != 'shop.product_details' ) {
$ii_page_required = true;
}
}
$ii_flypage = FLYPAGE;
$ii_flypage_required = false;
if( $ii_arr['flypage'] ) {
$ii_flypage = $db->getEscaped( vmget($ii_arr, 'flypage') );
if( $ii_flypage != FLYPAGE ) {
$ii_flypage_required = true;
}
}
} else if( !empty($ii_arr['category_id']) ) { // Category page
$ii_product_id = '';
$ii_cat_id = (int)$ii_arr['category_id'];
$ii_cat_id_required = true;
$ii_page = 'shop.browse';
$ii_page_required = false;
if( $ii_arr['page'] ) {
$ii_page = $db->getEscaped( vmget($ii_arr, 'page') );
if( $ii_page != 'shop.browse' ) {
$ii_page_required = true;
}
}
$ii_flypage = FLYPAGE;
$ii_flypage_required = false;
if( $ii_arr['flypage'] ) {
$ii_flypage = $db->getEscaped( vmget($ii_arr, 'flypage') );
if( $ii_flypage != FLYPAGE ) {
$ii_flypage_required = true;
}
}
} else if( !empty($ii_arr['page']) ) { // Non-Product/Non-Category page
$ii_product_id = '';
$ii_cat_id = '';
$ii_cat_id_required = false;
$ii_page = $ii_arr['page'];
$ii_page_required = true;
$ii_flypage = '';
$ii_flypage_required = false;
} else { // Default to finding the VM home page only
$ii_product_id = '';
$ii_cat_id = '';
$ii_cat_id_required = false;
$ii_page = 'shop.index';
$ii_page_required = true;
$ii_flypage = '';
$ii_flypage_required = false;
}
// Build the query
$q = "SELECT id FROM #__menu WHERE link='index.php?option=com_virtuemart' AND published=1";
$q .= " AND params LIKE '%product_id=$ii_product_id\\n%'"; // Required even if $ii_product_id is empty
$q .= " AND (params LIKE '%category_id=$ii_cat_id\\n%'"; // Required even if $ii_cat_id is empty
$q .= $ii_cat_id_required ? ")" : " OR params LIKE '%category_id=\\n%')";
$q .= " AND (params LIKE '%page=$ii_page\\n%'"; // Required even if $ii_page is empty
$q .= $ii_page_required ? ")" : " OR params LIKE '%page=\\n%')";
$q .= " AND (params LIKE '%flypage=$ii_flypage\\n%'"; // Required even if $ii_flypage is empty
$q .= $ii_flypage_required ? ")" : " OR params LIKE '%flypage=\\n%')";
$db->query( $q );
if( $db->next_record() ) {
$tmp_Itemid = $db->f("id");
}
This, with the changes in other recent posts now appears to fix all of my breadcrumbs problems
Regards
Phil