Custom Product Search - YMM

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #31130

I need to implement a custom search for YMM (year make model). There are, of course, several interfaces I could dream up to accomplish the task, however I will describe what I believe to be the easiest.

Prerequisites:
1. I have all of my products categorized and imported into my store (hikashop online store, that is).
2. I have all of my YMM data in a separate table in my database listed by product_code (SKU).

I would like to build a simple search form, with year, make, model. That form would request/pull the list of SKU's from my YMM data that match. I would then like to pass my list of SKU's to the hikashop product list page for display.

Please advise best course of action or alternatives to accomplish this task.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #31139

Hi,

You should be able to do that without any coding.
First, create custom fields of the table "product" via the menu Display->Custom fields for the year, make, model and enter the information for each product.
Then, create filters for each custom field via the menu Display->Filters following the documentation here:
www.hikashop.com/en/support/documentatio...-filter-listing.html
That should put search filters on the products listing so that your users can easily browse your products.

That can only be done in the Business edition of HikaShop.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #31315

Nicolas,

Thank you for your prompt responses. I have spent a few hours going over
different combinations of the example/solution you provided. However, I am
dealing with over 179,000 YMM/Product permutations, the data are too large
to use in the custom field format you suggested as well as too difficult to
maintain over the long term. I have to revert to a traditional YMM search
model.
The YMM search model needs to be a two part procedure.
1. Fetch the part numbers that match on YMM
2. Pull the product list from eCommerce system from YMM search results.
My design pattern would be thus: I create a module that does a YMM search
against my independent YMM/Product list.
Pass my search results containing Part Numbers to a Hikashops product filter
or product search module to build my final product list page.

Max


Hi,

Then, in that case, you can create a hikashop plugin implementing the
onBeforeProductListingLoad(&$filters) event:
www.hikashop.com/en/support/documentatio...reProductListingLoad

That way you will be able to dynamically generate the conditions in
the products listing query based on your search results (coming from
the $_GET, or the $_SESSION for example).

Best regards,
Nicolas


Nicolas,

Thank you for the direction. I have a quick question regarding the $filters array. Do you have an example or documentation on the format for that array.

Last edit: 12 years 11 months ago by mmccarthy.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #31347

the $filters array contains condition strings.

for example:
$filters = array('b.product_published=1','b.product_id IN(1,2,3,4,5,6,7)');

would be to display all the published products which have their id in the list 1,2,3,4,5,6,7

Note that you should only ADD filters to that array and not modify the conditions which are already in the array unless you really know what you're doing.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #31774

I've hit a brick wall and need some more advise. The thing holding me back is my limited experience developing in Joomla! I'm not sure where I include the onBeforeProductList method with my search results to create my Hikashop product listing. Do I need to send my search results to com_hikashop, do I need to create a menu-item associated to my root category and drop a product list module in there that loads a plugin with my modified filters? This is where I am grasping.

I've created my search module, under the "search" group; I've written my onSearch method in my search plugin, and return my list of part numbers based on the YMM selection;

My structure looks like this:

modules/mod_ymm_search
modules/tmpl/default.php -- builds my ymm search form
modules/helper.php -- gets my list of years makes and models for select boxes
modules/mod_ymm_search.php
modules/mod_ymm_search.xml

plugins/search/ymmSearch/ymmSearch.php -- has my custom onSearch method to pull part numbers by year make model.
plugins/search/ymmSearch/ymmSearch.xml

Right now, in my module, the search form action is set to:
index.php?option=com_hika&view=listing

There is a configurable parameter in my module for Itemid, that is not used at the moment.

My search plugin creates a record set modeled after the Hikashop search and the core Joomla! search plugins ( Anticipate having to modify this once I get my product list working, I suspect I'll have to do a left join on the products table to get the hikashop_products product_id.):

//Return the search results in an array
        foreach ($results as $row) {
            $rows[] = (object) array(
                'href' => 'index.php?option=com_hikashop&view=listing&part_number=' . $row->part_number,
                'title' => $row->part_number,
                'browsernav' => 1,
                // 'section' => 'searchplgSearchCoreYmmSearch',
                'created' => NULL
                );
        }

        return $rows;

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #31812

The module is great.
For the plugin, you should actually create a hikashop plugin implementing the onBeforeProductList function and not a search plugin.
Then, in your onBeforeProductList function, you should take the information from the post of the form of your module and based on it, pull your part numbers and add your condition to the $filters array given in parameter of the onBeforeProductList function.

So you're actually not the one loading the products. It's HikaShop which will do it for you. All you have to do is to add a condition to the query made by HikaShop to load the products so that HikaShop will only display your products.

Also, it would be better I think to direct your form to a HikaShop products listing menu and make sure that the "sub filter element" option of your menu is set to "all sub elements" so that it would display all the products if there is no condition added by your plugin.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #31852

Thank you Nicolas,

I get what you meant now by HS plugin instead, I appreciate your patience and time answering my questions regarding the mod/plugin. It is essentially working now, my YMM search is returning exactly the results I expect in a product listing. After going through the motions of learning the Joomla! search plugin, instituting the hikashop plugin was a breeze.

I have some front-end tweaking to do in my module to make the YMM search a bit more intelligent (ajaxy select/option creation based on valid YMM combinations) I expect to have that nailed down shortly.

One of the interesting issues I still need to address, however, is scenarios when YMM searches return no products matching the request (eg. there was never a "1937 Toyota La Baron", or the manufacture doesn't supply a product for a 2010 Ford Fiesta). What do you recommend I do to override the onBefore* method when no products are return in my initial YMM search?

Right now I catch the post request in the onBeforeProductListingLoad, run my query joined against my YMM data table and do a "product_id IN (...)" on my result set.

For now, do avoid any obtuse PHP notice/warnings, I have caught the empty result set in an if/else; if my results are empty I added a condition to the filter that I know will always return an empty result set, instead. I get a very nice blank page, with out any of the obnoxious PHP warnings or any indication to the user... that the results they searched for were invalid.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #31858

I would have recommended to do just that: add a condition which is not possible in that case so that it does not return any product.

You have several options for the message.
The easiest is to use the joomla mesaging system like that:
$app =& JFactory::getApplication();
$app->enqueueMessage('No products found for your search');

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #31888

Great! Thanks just what I was looking for.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32020

OK... last thing I thinks.

My results are coming up perfect now. Invalid results are messaging - except I get a duplicate message, that's a template issue our designer will take care of I think.

I'm getting some odd display issues now however. I think they are related to my plugin overriding params needed on the product listing page. Things like the pagination are missing when my final product listing is rendered sometimes. Default thumbnail size isn't loading properly. The bread crumbs are missing as well. Some of these are perhaps template issues some could be configuration/programming related?

I am calling a constructor:

public function __construct(&$subject, $config) {
        $this->loadLanguage('plg_search_hikashop_products');
        $this->loadLanguage('plg_search_hikashop_products_override');

        parent::__construct($subject, $config);
        if (!isset($this->params)) {
            $plugin = & JPluginHelper::getPlugin('hikashop');
            jimport('joomla.html.parameter');
            $this->params = new JParameter($plugin->params);
        }
        
    }
EDIT:
Additionally, I don't know how to handle pagination... apparently my designer fixed the "pagination not showing up" issue since posted.

I was testing pagination, my initial page load is correct - total counts, number of pages, etc. But navigating the pagination takes me to the selected page out our total product count, not the original search limits. How do I pass my original data set filters to the pagination "engine?"

Example:
YMM Search results 22 total; 2 pages; 20 per page.
If you click "page 2," "next," or "all" from the "limit" select options the pagination event/request takes you to page 2 of 395 (our total products).

I'm losing my original data set in the pagination request.

Guidance greatly appreciated, again.

Max

Last edit: 12 years 11 months ago by mmccarthy.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #32047

Yes, that's normal.
When you change the page, the information in the post is not sent since there is no form. So when you try to look for the data in the post you don't get anything.
You should store the search information in the session when you get it so that you can use it on the other pages when no information is in the post.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32051

Nicolas,
Can you point me at the documentation to tell me what data and format I need to save the session data as/is.

I am certain the session has started already within the joomla framework, so adding what I need to the super global $_SESSION isn't an issue... just the format and content necessary for Hikashop.

Do you suggest I set the session data in the module after form submit or in the plugin when I test for the super global $_POST elements from my YMM search?

Thank you in advance.

Max

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #32055

It's your module data that you need to save so I don't know the format :)
You should do that in the plugin when the $_POST is checked.
For example, if you have $_POST, you could do:
if(!isset($_POST)) $_POST = $_SESSION;
else $_SESSION = $_POST;

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32057

in the hikashop "namespace," under product listings, what does hikashop use to manage pagination? all i did was add a sub-plugin under the hikashop plugin. plugins/hikashop/my_ymm_plugin/my_ymm_plugin.php

then in my module, my form action is "index.php?option=com_hikashop&view=product&layout=listing"

as my plugin is under the hikashop namespace, overriding the onbeforeproduct... method the initial load is fine ... all the other pagination elements on the page though arent rendered with my initial filters as their base criteria for limits and offsets.. how do i pass my initial filters from the plugin onBeforeProductListLoad to the pagination in the view... i'm obviously missing a trivial step after my plugin onbeforeproductlistingload happens... do i have to override onbefore to look for my filters in the session too? not just _POST? did i just have an epiphany?

after my plugin feeds the product listing with product_id's in the $filter property... the hikashop product listing is rendered to the menu item as declared. there is some triggering here that i haven't fully grasped, because i have my itemid hidden input element in the module form that points to my "hidden" menu item presumably, reflected in the URI "index.php?option=com_hikashop&view=product&layout=listing&Itemid=xxx"

im not as comfortable w/ joomla routing as i should be perhaps... but i think i get most of whats going on.

from my module, i post the ymm search criteria, thats when my plugin steps in and does all the processing to pull up the product id list....in the onbefore* method its here that i presumed i needed to add in the handling for the hikashop product listing pagination.... do i have the whole business logic wrong? have i simply gotten lucky in my initial plugin rendering of my product list from the ymm search?

plugins/hikashop/ymm_search/ymm_search.php & ymm_search.xml

ymm_search.php has the onbeforeproductlistingload method. thats where i checked for my ymm module super global post variables....then i modified the hikashop product search plugin query to pull my product list and pushed my "product_id IN (...)" entry to the referenced $filters array on the onbefore* method.

i'm missing totally and completely how to keep that information for the pagination to work...once modified $filters are passed to the product list menu item.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32058

pagination is using javascript onclick and event handling with a .value=x to modify the query offset/limit... so i need to evaluate the get/post pasted in that event to calculate the limit offset needed with w/my initial filters which i will now store in session...

$_SESSION['YMM'] = '..., product_id IN(...) OFFSET 0 LIMIT 20'
if isset($_SESSION('YMM')) {
 $filters[] = $_SESSION['YMM']
}

how do i catch those offset/limit values are they an ajax/post or ajax/get? what is their variable name? the above only works once...then we need to fall back to the new page request for an offset and limit change.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #32067

You don't need to fiddle with the pagination system. The limit system in the query is already handled by HikaShop. You just need to always give the same filter on all the pages of the pagination, not just the first one.
All you need to do is to store your YMM in the session when you get the selection from the post so that when the pagination changes, you can look in the session instead of the post since the post information won't be transferred to the new page.

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32074

Ok, I added it as described:

if ((empty($post->search_make) || empty($post->search_model) || empty($post->search_year))) {
            if(isset($_SESSION['YMM']) && !empty($_SESSION['YMM'])){
                $filters[] = 'a.product_id IN (' . implode(',', $_SESSION['YMM']) . ')';
            }

            $filters = $filters;
        } else {
           // DO MY YMM SEARCH LOOK UP AND ADD TO $filter MY YMM SEARCH RESULTS
        }

It worked like a charm on when dealing with my YMM search results, but as I suspected, now all other page loads from the other menus are picking up that session variable.

How do I check to see that the page loaded isn't my product listing menu item? Can I check the referrer some how? Unset my $_SESSION as soon as a different menu item is requested?

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32077

i cheated... i checked the filters array for the entry "a.category_id IN (2)" (that's my root products category... its only loaded by YMM search.)

If it's not in the $filters then I unset my session variable YMM.

Please Log in or Create an account to join the conversation.

  • Posts: 82906
  • Thank you received: 13378
  • MODERATOR
12 years 11 months ago #32078

You could have also checked the Itemid parameter of the URL but your solution is OK too :)

Please Log in or Create an account to join the conversation.

  • Posts: 23
  • Thank you received: 0
12 years 11 months ago #32087

I have a new issue... that has propagated itself when we ported the site to our development server. My localhost instance of the site uses the same database as the dev server as a side note. However, some of the results aren't rendering correctly on the dev server.

When I search 2010, Chevy, Cobalt for All products (category 2)... both sites return 34 products.

When I refine the same YMM search to look for a different category, my localhost results return correct. Render the refined result set. When I run the same refined search on the dev server the filters array matches but the products aren't rendered.

I suspect it may be a short tags issue or something like that in the server config but I need to trace the exact issue... any ideas?

EDIT:::: It was cache issue. Cleared cache from administrator and all is good now.

Last edit: 12 years 11 months ago by mmccarthy.

Please Log in or Create an account to join the conversation.

Time to create page: 0.092 seconds
Powered by Kunena Forum