|
As mentioned in an earlier post, I'm currently developing an e-commerce site for the company I work for. I toyed with the idea of writing it from scratch but thought I'd investigate some open source solutions first. I finally settled on a combination of Joomla! for the CMS (content management system) and Virtuemart for the shopping cart solution. The upshot of all this is that the majority of the work has been done for you. You then just have to bend it to your will! That's not always an easy task though! Anyway, one downside to the Virtuemart shopping cart software is it's search engine. It has what I consider to be three, rather large flaws: Basic search: When performing a general search spanning multiple categories, the results do not show which categories the products are from. Also, the search does not take into account the category names! Advanced Search: When performing an advanced search, if you search within a category which has no products but the categories within that category do have products, the search will return no results. Category drop-down box: The advanced search category drop-down box fails to list categories in a meaningful way. It literally just presents you with and unformatted list of all categories, regardless of their parent or child categories. So, I set to work on resolving these issues! The following applies to Virtuemart 1.1.2 running in Joomla! 1.5.x I started with the category drop-down. Now, in the Virtuemart control panel there are a couple of drop-down boxes that display categories properly, in a tree-style format, so you know exactly how all the categories are related. I decided to track down the code that generated these boxes and see if they could be used in the shop.search (advanced search) page. It took some doing but I finally came up stupidly simple answer: add the following code to the top of administrator/components/com_virtuemart/html/shop.search.php (Line 21) require_once( CLASSPATH .'ps_product_category.php'); $ps_product_category = new ps_product_category(); then replace the standard dropdown box code with the following (Line 50): <select class="inputbox" name="search_category"> <option value=""><?php echo $VM_LANG->_('SEL_CATEGORY') ?></option> <?php $ps_product_category->list_tree(); ?> </select> Done! You now have a much more meaningful drop-down box :) Next up, I wanted to get the products displayed in the results of a search to display what category they belonged to. Now, this was a bit of a bugger but at the eleventh hour, I came up with a solution: To display the category "breadcrumbs", you need to call the get_navigation_list() function in administrator/components/com_virtuemart/classes/ps_product_category.php (Line 1257) to go through the database and find out all the parent categories of a product. Now this function works fine but if you call it within a loop, because it uses a static counter, things go a bit screwy. So, what you have to do is copy the function and modify it slightly by zero-ing the count value as you call it. Paste this into the above file: function get_navigation_list_mod($category_id,$i) { $db = new ps_DB; static $category_list = array(); if ($i == ""){ $category_list = ""; } $q = "SELECT category_id, category_name,category_parent_id FROM #__{vm}_category, #__{vm}_category_xref WHERE "; $q .= "#__{vm}_category_xref.category_child_id='$category_id' "; $q .= "AND #__{vm}_category.category_id='$category_id'"; $db->setQuery($q); $db->query(); $db->next_record(); $category_list[$i]['category_id'] = $db->f("category_id"); $category_list[$i]['category_name'] = $db->f("category_name"); if ($db->f("category_parent_id")) { $i++; array_merge( $category_list, $this->get_navigation_list_mod($db->f("category_parent_id"),$i) ); } return $category_list; }
Then, you'll need to add the following code to administrator/components/com_virtuemart/html/shop.browse.php (Line 453) $products[$i]['category_id'] = $db_browse->f("category_id"); $products[$i]['category_name'] = $db_browse->f("category_name"); $products[$i]['product_id'] = $db_browse->f("product_id");
and then the following to the $fieldnames variable in administrator/components/com_virtuemart/html/shop_browse_queries.php (Line 36) `#__{vm}_category`.`category_name`
Finally, you'll want to add the following code to the top of your category browse template which, by default, is components/com_virtuemart/themes/default/templates/browse/browse_1.php (Line 3) require_once (CLASSPATH."ps_product_category.php"); $ps_product_category = new ps_product_category; $tpl = vmTemplate::getInstance();
...and then add the code that pulls it all together and displays the breadcrumbs. Obviously, where you put the display code (below) is down to whether you have a virtuemart theme installed or whether you've modified the default templates so put the following code where you think it looks best: <div class="pathway"> <?php // Check if a product is in multiple categories $db_cat = new ps_DB; $db_cat->query("SELECT category_id FROM #__{vm}_product_category_xref WHERE product_id='$product_id'"); // Set up the CMS pathway while ($db_cat->next_record()) { $category_id = $db_cat->f('category_id'); $category_list = array_reverse( $ps_product_category->get_navigation_list_mod($category_id,'') ); $pathway = $ps_product_category->getPathway( $category_list ); $tpl->set( 'pathway', $pathway ); $tpl->set( 'category_id', $category_id); $tpl->set( 'category_name', $category_name ); $navigation_pathway = $tpl->fetch( 'common/pathway.tpl.php'); $tpl->set( 'navigation_pathway', $navigation_pathway ); if ($keyword1 !='') { echo $navigation_pathway; }?><br /> <?php } ?> </div>
Deep breath, refresh (make sure the Joomla cache is disabled and cleaned!) and check it out! :D Unfortunatly, doing it via the browse template means that it'll show the the breadcrumbs when you're browsing a category too but I kinda like it that way. If I can be bothered, I'll look into displaying it on the search results page only at a later date. The final task of sorting out the basic search was going to be a biggie and one I wasn't sure I'd be up to without re-writing the entire Virtuemart search process. However, to my utter surprise, by adding the "breadcrumbs" to the individual products in the search results, I had inadvertently already sorted out the problem! Well, kind of anyway - it works in the advanced search, just not the basic search but that's good enough for me, i'll just direct customers directly to the advanced search page instead! :D Now, don't ask me how that works because in reality it shouldn't - changing the format of the search results shouldn't have any effect whatsoever on the initial search itself but for some strange reason it does and I for one am not going to complain! :P So there you have it, VM is easy to tame when you know how ;) ...oh and yeah, I know this doesn't exactly class as "hacking the Virtuemart search engine" but hell, it's close enough! :P EDIT: Ok, I decided that, instead of fixing the issue with the basic search, I would just replace the basic search with elements of the advanced search. This gives customers the conveniance of instant search access coupled with the functionality of my advanced search hack! :D To do this, replace the search box code in whichever module is showing your basic search box - mod_virtuemart for example - with the code below: modules/mod_virtuemart/mod_virtuemart.php <!--BEGIN Search Box --> <tr> <td colspan="2"> <hr /> <form action="<?php echo URL ?>index.php" method="post" name="adv_search"> <input type="hidden" name="page" value="shop.browse" /> <input type="hidden" name="option" value="com_virtuemart" /> <input type="hidden" name="Itemid" value="<?php echo $sess->getShopItemid() ?>" /> Search:<br /> <input class="inputbox" type="text" name="keyword1" size="22"/><br /><br /> <input type="submit" class="button" name="search" value="<?php echo $VM_LANG->_('PHPSHOP_SEARCH_TITLE') ?>" /><a href="/<?php echo $sess->url($mm_action_url."index.php?option=com_virtuemart&page=shop.search") ?>"> Advanced Search </a> <br /> </form>
EDIT 2: I've made some additions to the search result product breadcrumbs allowing multiple breadcrumb trails to be shown for products that are in multiple categories :) EDIT 3: Fixed get_navigation_list_mod function to allow multiple category depths to show correctly - damn static variables!!
|