'index.php?option=com_newsfeeds&view=newsfeed&catid='.$row->catslug.'&id='.$row->slug, 'title' => $row['name'], 'section' => $searchnameofplugin, 'created' => $row['date'], 'text' => $row['name'], 'browsernav' => '1' ); */ defined('_JEXEC') or die('Restricted access'); class plgHikashopCoreProductSearch extends JPlugin { //JPlugin { const YMM_CATEGORY_ID = 152; const PART_SEARCH_CATEGORY_ID = 207; const HIKASHOP_ALL_PRODUCTS_CATEGORY_ID = 2; const PART_SEARCH_CATEGORY_INPUT_PREFIX = 'hika_'; private $Itemid = NULL; private $search_type = NULL; private $defaultOrdering = 'code'; private $_input_filters = array(); private $default_input_filters = array( 'b.product_published=1', 'b.product_type=\'main\'', ); private $search_category_id = NULL; private $db = NULL; private $_filters = array(); private $post_category_prefix = 'vs_'; private $_app = NULL; private $filters_set = FALSE; public function __construct(&$subject, $config) { $this->loadLanguage('plg_search_hikashop_products'); $this->loadLanguage('plg_search_hikashop_products_override'); $this->db = & JFactory::getDBO(); parent::__construct($subject, $config); if (!isset($this->params)) { $plugin = & JPluginHelper::getPlugin('hikashop'); jimport('joomla.html.parameter'); $this->params = new JParameter($plugin->params); } $this->_app = & JFactory::getApplication(); $this->Itemid = JRequest::getVar('Itemid', 0, 'GET'); $this->search_type = JRequest::getVar('core_search', NULL, 'POST'); // set the core_search session variable so we can tell our custom layout to render the product // listing and search results properly if ((!is_null($this->search_type) ) && ($this->Itemid == self::PART_SEARCH_CATEGORY_ID || $this->Itemid == self::YMM_CATEGORY_ID)) { $_SESSION['core_search'] = $this->search_type; $this->_setPostCategoryPrefix(); } } public function onBeforeProductListingLoad(&$filters) { if (is_null($this->search_type) && (isset($_SESSION['core_search']) && $_SESSION['core_search'] !== FALSE)) { // no search type was posted lets look for it in the session data $this->search_type = $_SESSION['core_search']; $this->_checkSearchCriteria($filters); } if (!$this->filters_set && $this->search_type == 'ymm') { $this->_ymmSearch($filters); } else if (!$this->filters_set && $this->search_type == 'parts_search') { $this->_partsSearch($filters); } $filters = $filters; } private function _setPostCategoryPrefix() { switch ($this->search_type) { case 'parts_search': $this->post_category_prefix = self::PART_SEARCH_CATEGORY_INPUT_PREFIX; break; case 'ymm': default: break; } } /** * create the list of valid field names to test for when issueing a Part Search * * @return array */ private function _getPartSearchPostFields() { // get a list of valid product fields to use in the product search $validFieldsQry = "SELECT field_namekey FROM #__hikashop_field WHERE field_namekey LIKE '%product_attr_%' AND field_table = 'product'"; $this->db->setQuery($validFieldsQry); $fieldList = $this->db->loadObjectList(); return $fieldList; } /** * create the list of valid field names to test for when issueing a YMM Search * @return array */ private function _getYMMPostFields() { $fieldList = array(); $fieldList[] = (object) array('field_namekey' => 'ymm_year'); $fieldList[] = (object) array('field_namekey' => 'ymm_make'); $fieldList[] = (object) array('field_namekey' => 'ymm_model'); return $fieldList; } private function _unsetDefaultHikaCategoryFilters(&$filters) { foreach ($filters as $key => $filter) { if (preg_match('/a\.category_id IN/', $filter) == 1) { unset($filters[$key]); } } unset($_SESSION['core_search_category']); $filters = $filters; } private function _setSearchCategoryId() { // set the posted category to search against $posted = JRequest::getVar($this->post_category_prefix . 'category', NULL, 'POST'); if (!is_null($posted)) { $this->search_category_id = $posted; } else if (isset($_SESSION['core_search_category'])) { $this->search_category_id = $_SESSION['core_search_category']; } else { $this->search_category_id = self::HIKASHOP_ALL_PRODUCTS_CATEGORY_ID; } } private function _setCategoryFilters(&$filters, $categoryId) { if ($categoryId != self::HIKASHOP_ALL_PRODUCTS_CATEGORY_ID) { $filters[] = 'a.category_id IN (' . $categoryId . ')'; } else { $filters[] = 'a.category_id IN (' . self::HIKASHOP_ALL_PRODUCTS_CATEGORY_ID . ')'; } $_SESSION['core_search_category'] = $categoryId; } private function _getPostSearchFields() { // get the posted fields appropriate for the search type switch ($this->Itemid) { case self::YMM_CATEGORY_ID : $fieldList = $this->_getYMMPostFields(); break; case self::PART_SEARCH_CATEGORY_ID : $fieldList = $this->_getPartSearchPostFields(); break; default: $fieldList = array(); break; } $post = array(); // add the cateogry search to our post conditions for later use in the view. $post[$this->post_category_prefix . 'category'] = $this->search_category_id; // parse the POST array for the valid product search fields foreach ($fieldList as $_field) { $field = $_field->field_namekey; $posted = JRequest::getVar($field, NULL, 'POST'); if (isset($_POST[$field]) && strlen($posted) > 0) { $post[$field] = $posted; } } // put the search criteria into session for use in the views $_SESSION[$this->search_type . '_conditions'] = $post; unset($post[$this->post_category_prefix . 'category']); return (empty($post)) ? FALSE : (object) $post; } private function _checkSearchCriteria(&$filters) { if ($this->search_type !== FALSE && (isset($_SESSION[$this->search_type]) && !empty($_SESSION[$this->search_type]))) { $filters[] = 'a.product_id IN (' . implode(',', $_SESSION[$this->search_type]) . ')'; // unset the categories filter $this->_unsetDefaultHikaCategoryFilters($filters); // set the category id accordingly and set the category filter $this->_setSearchCategoryId(); $this->_setCategoryFilters($filters, $this->search_category_id); $this->filters_set = TRUE; } else { $this->_initializeCoreSearch(); } } private function _initializeCoreSearch() { unset($_SESSION[$this->search_type]); unset($_SESSION[$this->search_type . '_conditions']); unset($_SESSION['core_search_category']); $_SESSION['core_search'] = FALSE; } private function _getProductOrdering() { // default product listing order - override the hika default of popular to product_code (sku) $ordering = $this->defaultOrdering; switch ($ordering) { case 'alpha': $order = 'a.product_name ASC'; break; case 'newest': $order = 'a.product_modified DESC'; break; case 'oldest': $order = 'a.product_created ASC'; break; case 'popular': $order = 'a.product_hit DESC'; break; case 'code': $order = 'a.product_code DESC'; break; default: $order = 'a.product_name DESC'; break; } return $order; } private function _hasHikashopHelper() { if (!include_once(rtrim(JPATH_ADMINISTRATOR, DS) . DS . 'components' . DS . 'com_hikashop' . DS . 'helpers' . DS . 'helper.php')) { return false; } return TRUE; } /** * * @param array $filters passed by reference, set filters for custom product search * @param string $select - takes a custom select clause to apply to query * @param string $leftjoin - string containing custom joins for search query * @param array $groupby array list of table-alias.columns to group by * @param string $order string list of columns to order by * @param int $limit * @param array $mainRows set by reference, passes result set of query back for further processing if nessasary * @param int $new_page used for pagination */ private function _getHikashopProductFilterResult(&$filters, $select=NULL, $leftjoin=NULL, $groupby=NULL, $order=NULL, $limit=NULL, &$mainRows=NULL, $new_page=NULL) { /** * @TODO the Core101 product search does not fully support multi language options */ // do some hikashop translation work $trans = hikashop_get('helper.translation'); $multi = $trans->isMulti(); $rows = array(); $new_page = (is_null($new_page)) ? (int) $this->params->get('new_page', '1') : $new_page; $select = (is_null($select)) ? ' a.product_id AS id, a.product_code as `code`, a.product_name AS title, a.product_created AS created , a.product_description AS text, ' . $new_page . ' AS browsernav' : $select; $count = 0; // Build our query finally - based on our limit parameter get the initial list of products if ($limit) { $groupby = is_null($groupby) ? "" : ' GROUP BY ' . implode(', ', $groupby); $query = ' SELECT ' . $select . ' FROM ' . hikashop_table('product') . ' AS a ' . $leftjoin . ' WHERE ' . implode(' AND ', $this->_input_filters) . $groupby . ' ORDER BY ' . $order; $this->db->setQuery($query, 0, $limit); // set the mainRows array $mainRows = $this->db->loadObjectList("id"); if (!empty($mainRows)) { foreach ($mainRows as $k => $main) { $rows[$k] = $main; } $count = count($rows); } } if ($count) { if ($multi && !empty($lg)) { $query = ' SELECT * FROM ' . hikashop_table('jf_content', false) . ' WHERE reference_table=\'hikashop_product\' AND language_id=\'' . $lg . '\' AND published=1 AND reference_id IN (' . implode(',', array_keys($rows)) . ')'; $this->db->setQuery($query); $trans = $this->db->loadObjectList(); foreach ($trans as $item) { foreach ($rows as $key => $row) { if ($row->id == $item->reference_id) { if ($item->reference_field == 'product_name') { $row->title = $item->value; } elseif ($item->reference_field == 'product_description') { $row->text = $item->value; } else { $row->title = $item->value; } break; } } } } $parent = ''; $item_id = $this->params->get('item_id', ''); $menuClass = hikashop_get('class.menus'); $Itemid = ""; $menus = array(); if (!empty($item_id)) { $Itemid = '&Itemid=' . $item_id; if ($this->params->get('full_path', 1)) { $menuData = $menus[$item_id] = $menuClass->get($item_id); if (!empty($menuData->hikashop_params['selectparentlisting'])) { $parent = '&category_pathway=' . (int) $menuData->hikashop_params['selectparentlisting']; } } } $itemids = array(); foreach ($rows as $k => $row) { /** * the following code is used by the search plugin - not necessary for our modified hikashop plugin */ if (empty($item_id) && !empty($row->category_id)) { if (!isset($itemids[$row->category_id])) $itemids[$row->category_id] = $menuClass->getItemidFromCategory($row->category_id); $item_id = $itemids[$row->category_id]; if (!empty($item_id)) { $Itemid = '&Itemid=' . $item_id; if ($this->params->get('full_path', 1)) { if (!isset($menus[$item_id])) $menus[$item_id] = $menuClass->get($item_id); $menuData = $menus[$item_id]; if (!empty($menuData->hikashop_params['selectparentlisting'])) { $parent = '&category_pathway=' . (int) $menuData->hikashop_params['selectparentlisting']; } } $item_id = ''; } } // these wont actually be used - they are from the search plugin $rows[$k]->href = hikashop_completeLink('product&task=show&name=' . strtolower(preg_replace('#[^a-z0-9_-]#i', '', $row->title)) . '&cid=' . $row->id . $Itemid . $parent); $rows[$k]->section = JText::_('PRODUCT'); // these are the product id's we will send to the hikashop filters array $this->_filters[] = $row->id; } } if (empty($this->_filters)) { // no search results were returned so we will set a filter that will always return empty $filters[] = 'a.product_id=NULL'; $this->_app->enqueueMessage('Your search did not return any results. Please try another search.'); } else { // put the search results into session for future use in pagination $_SESSION[$this->search_type] = $this->_filters; // add the filter that includes our list of product id $filters[] = 'a.product_id IN (' . implode(',', $this->_filters) . ')'; } } private function _partsSearch(&$filters) { // unset the default categories filter $this->_unsetDefaultHikaCategoryFilters($filters); // set the category ID based on post or session $this->_setSearchCategoryId(); // set the filter categories now based on the user selection from the module $this->_setCategoryFilters($filters, $this->search_category_id); $post = $this->_getPostSearchFields(); // return an empty search result if search criteria for YMM are not satisfied if ($post !== FALSE) { if (!$this->_hasHikashopHelper()) { return array(); } $limit = $this->params->def('search_limit', 50); // Set the query order by condition $order = $this->_getProductOrdering(); // add product search criteria to filters array foreach ($post as $field => $value) { $this->_input_filters[] = 'a.' . $field . '=\'' . $value . '\''; } // do the real work now $this->_getHikashopProductFilterResult($filters, NULL, NULL, NULL, $order, $limit); } } private function _ymmSearch(&$filters) { // unset the default categories filter $this->_unsetDefaultHikaCategoryFilters($filters); // set the category ID based on post or session $this->_setSearchCategoryId(); // set the filter categories now based on the user selection from the module $this->_setCategoryFilters($filters, $this->search_category_id); $post = $this->_getPostSearchFields(); // return an empty search result if search criteria for YMM are not satisfied if ($post !== FALSE) { if (!$this->_hasHikashopHelper()) { return array(); } $new_page = (int) $this->params->get('new_page', '1'); // add the group concat on the ymm fitment notes to be passed back and set in session for product detail view $select = ' a.product_id AS id, a.product_code as `code`, a.product_name AS title, a.product_created AS created , a.product_description AS text, GROUP_CONCAT(DISTINCT ymm_search.notes SEPARATOR ",") as fitment_notes, "' . $new_page . '" AS browsernav'; $limit = $this->params->def('search_limit', 50); // Set the query order by condition $order = $this->_getProductOrdering(); // add YMM search to search array $this->_input_filters = array( 'a.product_published=1', 'a.product_type=\'main\'', "`ymm_search`.`year` = '{$post->ymm_year}'", "`ymm_search`.`make` = '{$post->ymm_make}'", "`ymm_search`.`model` = '{$post->ymm_model}'"); // add in YMM input_filters as necessary $leftjoin = ' INNER JOIN ymm_search ON a.`product_code`=`ymm_search`.`part_number`'; $groupby = array('a.product_code'); // do the real work now - initialize the fitment notes for display in the view $mainRows = array(); $this->_getHikashopProductFilterResult($filters, $select, $leftjoin, $groupby, $order, $limit, $mainRows, $new_page); // set the fitment notes for future use in the view if (!empty($mainRows)) { foreach ($mainRows as $k => $main) { if (!empty($main->fitment_notes)) { $session = JFactory::getSession(); $fitnotes = array(); $fitnotes[$main->code][$post->ymm_year][$post->ymm_make][$post->ymm_model] = $main->fitment_notes; $session->set('ymm_fitment_notes', $fitnotes); $_SESSION['ymm_fitment_notes'][$main->code][$post->ymm_year][$post->ymm_make][$post->ymm_model] = $main->fitment_notes; } } } } } }