iceweird Posted May 16, 2016 Share Posted May 16, 2016 (edited) Hi, i'm on prestashop 1.6.1.2 with multi stores enabled. They are all in the same domain, the main reason is that i have groups of clients that have permissions over showing prices and others don't, but everyone can see the products in all stores. Is it possible to change the module or is there a module to quick search in more than 1 shop in multi stores mode ? Thanks in advance. edit: [sOLVED] Edited June 13, 2016 by iceweird (see edit history) Link to comment Share on other sites More sharing options...
Simonas Invertus Posted May 17, 2016 Share Posted May 17, 2016 Everything is possible, but it is very complicated. Do you have the same products in all shops? If yes, does the products have different prices? If yes, what would search have to display? Product from every shop with different prices? What happens if one shop is out of stock and others are not? If no. If you have different products in different shops, how cart should work? Link to comment Share on other sites More sharing options...
iceweird Posted May 17, 2016 Author Share Posted May 17, 2016 Hi, 3 stores, Electric & Electronic Devices , Energy , Engineering There's no overlap of products, all the stores have different products. The cart is shared, the clients are shared also. All clients and guests have permissions to see all the products. Some groups have permissions to see prices on some stores and other clients on another stores. I hope that clarifies a bit more. Thank you for your input. Link to comment Share on other sites More sharing options...
Simonas Invertus Posted May 17, 2016 Share Posted May 17, 2016 I never seen such configuration before, there for I do not think that there is a module for that. You need to hire a developer to do custom job for you. Link to comment Share on other sites More sharing options...
iceweird Posted May 18, 2016 Author Share Posted May 18, 2016 Thank you Simonas. @vekia , any other ideas ? Thanks Link to comment Share on other sites More sharing options...
iceweird Posted May 19, 2016 Author Share Posted May 19, 2016 anyone with any ideas ? Link to comment Share on other sites More sharing options...
rocky Posted June 1, 2016 Share Posted June 1, 2016 The solution is probably more complicated than this, but you could try overriding classes/Search.php, copy the entire find function and then remove the following code on lines 206 and 232: AND sw.id_shop = '.$context->shop->id.' and lines 250-254 from: '.Shop::addSqlAssociation('product', 'p', false).' WHERE c.`active` = 1 AND product_shop.`active` = 1 AND product_shop.`visibility` IN ("both", "search") AND product_shop.indexed = 1 to: WHERE c.`active` = 1 Hopefully, by removing all references to the current shop, all shops will be searched. Anyway, I hope it gives you an idea. Link to comment Share on other sites More sharing options...
iceweird Posted June 1, 2016 Author Share Posted June 1, 2016 The solution is probably more complicated than this, but you could try overriding classes/Search.php, copy the entire find function and then remove the following code on lines 206 and 232: AND sw.id_shop = '.$context->shop->id.' and lines 250-254 from: '.Shop::addSqlAssociation('product', 'p', false).' WHERE c.`active` = 1 AND product_shop.`active` = 1 AND product_shop.`visibility` IN ("both", "search") AND product_shop.indexed = 1 to: WHERE c.`active` = 1 Hopefully, by removing all references to the current shop, all shops will be searched. Anyway, I hope it gives you an idea. Thanks for the tip rocky. Going to see where it takes me and i'll give a feedback soon. Link to comment Share on other sites More sharing options...
iceweird Posted June 2, 2016 Author Share Posted June 2, 2016 Hi,so i managed to get it parcialy working, i'm getting the right products on both the ajax quick search and search results.Deleting the lines didn't affect the end result Instead of deleting those lines i added 2 querys to get the stores inside the shop group (i have 2 groups).so i did a bit more digging into the code, and the other bottlenecks were the Shop::addSqlAssociation , Shop::addSqlRestrictionOnLang , that were forcing the shop id .I printed out those parts of the querys and swaped them to force all the stores in the current shop group.Here's the code i ended up with. public static function find($id_lang, $expr, $page_number = 1, $page_size = 1, $order_by = 'position', $order_way = 'desc', $ajax = false, $use_cookie = true, Context $context = null,$id_category=null) { if (!$context) $context = Context::getContext(); $db = Db::getInstance(_PS_USE_SQL_SLAVE_); if ($page_number < 1) $page_number = 1; if ($page_size < 1) $page_size = 1; if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)) return false; $intersect_array = array(); $score_array = array(); $words = explode(' ', Search::sanitize($expr, $id_lang, false, $context->language->iso_code)); // 2 querys to find the id_shop_group and the stores that are in it, and stringify the stores into a variable $id_grupo = $db->executeS('SELECT id_shop_group FROM '._DB_PREFIX_.'shop WHERE id_shop='.$context->shop->id); $lojas_arr = $db->executeS('SELECT id_shop FROM '._DB_PREFIX_.'shop WHERE id_shop_group='.$id_grupo[0]['id_shop_group']); $lojas=''; foreach($lojas_arr as $loja){ if($lojas!=''){ $lojas.=','; } $lojas.=$loja['id_shop']; } foreach ($words as $key => $word) if (!empty($word) && strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN')) { $word = str_replace('%', '\\%', $word); $word = str_replace('_', '\\_', $word); $intersect_array[] = 'SELECT si.id_product FROM '._DB_PREFIX_.'search_word sw LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word WHERE sw.id_lang = '.(int)$id_lang.' AND sw.id_shop IN('.$lojas.') AND sw.word LIKE '.($word[0] == '-' ? ' \''.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).'%\'' : '\''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'' ); if ($word[0] != '-') $score_array[] = 'sw.word LIKE \''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\''; } else unset($words[$key]); if (!count($words)) return ($ajax ? array() : array('total' => 0, 'result' => array())); $score = ''; if (count($score_array)) $score = ',( SELECT SUM(weight) FROM '._DB_PREFIX_.'search_word sw LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word WHERE sw.id_lang = '.(int)$id_lang.' AND sw.id_shop IN('.$lojas.') AND si.id_product = p.id_product AND ('.implode(' OR ', $score_array).') ) position'; $sql_groups = ''; if (Group::isFeatureActive()) { $groups = FrontController::getCurrentCustomerGroups(); $sql_groups = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1'); } $results = $db->executeS(' SELECT cp.`id_product`, pl.name FROM `'._DB_PREFIX_.'category_product` cp '.(Group::isFeatureActive() ? 'INNER JOIN `'._DB_PREFIX_.'category_group` cg ON cp.`id_category` = cg.`id_category`' : '').' INNER JOIN `'._DB_PREFIX_.'category` c ON cp.`id_category` = c.`id_category` INNER JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product` INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON cp.`id_product` = pl.`id_product` LEFT JOIN ps_product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop IN('.$lojas.')) WHERE c.`active` = 1 '.($id_category != null? 'AND c.`id_category` = '.$id_category.'':'').' AND product_shop.`active` = 1 AND product_shop.`visibility` IN ("both", "search") AND product_shop.indexed = 1 '.$sql_groups.' GROUP BY cp.id_product'); $eligible_products = array(); foreach ($results as $row) $eligible_products[] = $row['id_product']; foreach ($intersect_array as $query) { $eligible_products2 = array(); foreach ($db->executeS($query) as $row) $eligible_products2[] = $row['id_product']; $eligible_products = array_intersect($eligible_products, $eligible_products2); if (!count($eligible_products)) return ($ajax ? array() : array('total' => 0, 'result' => array())); } $eligible_products = array_unique($eligible_products); $product_pool = ''; foreach ($eligible_products as $id_product) if ($id_product) $product_pool .= (int)$id_product.','; if (empty($product_pool)) return ($ajax ? array() : array('total' => 0, 'result' => array())); $product_pool = ((strpos($product_pool, ',') === false) ? (' = '.(int)$product_pool.' ') : (' IN ('.rtrim($product_pool, ',').') ')); if ($ajax) { $sql = 'SELECT DISTINCT p.id_product, pl.name pname, cl.name cname, cl.link_rewrite crewrite, pl.link_rewrite prewrite '.$score.' FROM '._DB_PREFIX_.'product p INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON ( p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.' ) LEFT JOIN ps_product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop IN('.$lojas.')) INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON ( product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$id_lang.' ) WHERE p.`id_product` '.$product_pool.' ORDER BY position DESC LIMIT 10'; return $db->executeS($sql); } if (strpos($order_by, '.') > 0) { $order_by = explode('.', $order_by); $order_by = pSQL($order_by[0]).'.`'.pSQL($order_by[1]).'`'; } $alias = ''; if ($order_by == 'price') $alias = 'product_shop.'; else if ($order_by == 'date_upd') $alias = 'p.'; $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`, MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` manufacturer_name '.$score.', MAX(product_attribute_shop.`id_product_attribute`) id_product_attribute, DATEDIFF( p.`date_add`, DATE_SUB( NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY ) ) > 0 new FROM '._DB_PREFIX_.'product p LEFT JOIN ps_product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop IN('.$lojas.')) INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON ( p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.' ) LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (p.`id_product` = pa.`id_product`) LEFT JOIN ps_product_attribute_shop product_attribute_shop ON (product_attribute_shop.id_product_attribute = pa.id_product_attribute AND product_attribute_shop.id_shop IN('.$lojas.')) '.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop).' LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'. Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').' LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') WHERE p.`id_product` '.$product_pool.' GROUP BY product_shop.id_product '.($order_by ? 'ORDER BY '.$alias.$order_by : '').($order_way ? ' '.$order_way : '').' LIMIT '.(int)(($page_number - 1) * $page_size).','.(int)$page_size; $result = $db->executeS($sql); // Add DISTINCT(p.id_product) so we don't get duplicates $sql = 'SELECT COUNT(DISTINCT(p.id_product)) FROM '._DB_PREFIX_.'product p LEFT JOIN ps_product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop IN('.$lojas.')) INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON ( p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.' ) LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` WHERE p.`id_product` '.$product_pool; $total = $db->getValue($sql); if (!$result) $result_properties = false; else $result_properties = Product::getProductsProperties((int)$id_lang, $result); return array('total' => $total,'result' => $result_properties); } Now i'm faced with another problem, when you click the product it doesn't redirects to the right store, and displays a 404 error page instead. Any ideas ? Link to comment Share on other sites More sharing options...
rocky Posted June 2, 2016 Share Posted June 2, 2016 My guess is that PrestaShop is checking whether the product is in the current store and is generating a 404 error if it isn't. If that is the case, you could either disable that check or change the domain of the product URLs to the shop they belong to. Link to comment Share on other sites More sharing options...
iceweird Posted June 2, 2016 Author Share Posted June 2, 2016 My guess is that PrestaShop is checking whether the product is in the current store and is generating a 404 error if it isn't. If that is the case, you could either disable that check or change the domain of the product URLs to the shop they belong to. Hi rocky, do you know where's the product url , so i can see if i can change it ? Link to comment Share on other sites More sharing options...
rocky Posted June 3, 2016 Share Posted June 3, 2016 I've traced the code in PrestaShop v1.6.1.5 and I think it is the following on line 4279 of classes/Product.php that generates the link: $row['link'] = $context->link->getProductLink((int)$row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']); I think if you override the getProductProperties function and change the line to the following, it may help: $row['link'] = $context->link->getProductLink((int)$row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13'], null, $row['id_shop_default']); I haven't tested this code, but I hope passing the product's default shop ID into the function that generates the product link will cause the domain of that shop to be used instead of the current shop. Good luck. Link to comment Share on other sites More sharing options...
iceweird Posted June 3, 2016 Author Share Posted June 3, 2016 Yup, you're right. I managed to figure it out and was precisely doing that, and it works, the link changes to the correct store. But as soon as it redirects, it shows up a blank page... i'll have to debug that now i'll give some feedback soon. Thank you rocky for the tips. Link to comment Share on other sites More sharing options...
iceweird Posted June 13, 2016 Author Share Posted June 13, 2016 Problem solved! I've created an override for the getProductLink function in the Link class. public function getProductLink($product, $alias = null, $category = null, $ean13 = null, $id_lang = null, $id_shop = null, $ipa = 0, $force_routes = false, $relative_protocol = false, $add_anchor = false) { $dispatcher = Dispatcher::getInstance(); if (!$id_lang) { $id_lang = Context::getContext()->language->id; } if (is_object($product)){ $id_produto=$product->id; }else{ $id_produto=$product; } $db = Db::getInstance(_PS_USE_SQL_SLAVE_); $prod = $db->executeS('SELECT id_shop_default FROM '._DB_PREFIX_.'product WHERE id_product='.$id_produto); $id_shop = $prod[0]['id_shop_default']; $url = $this->getBaseLink($id_shop, null, $relative_protocol).$this->getLangLink($id_lang, null, $id_shop); if (!is_object($product)) { if (is_array($product) && isset($product['id_product'])){ $product = new Product($product['id_product'], false, $id_lang, $id_shop); } elseif ((int)$product) { $product = new Product((int)$product, false, $id_lang, $id_shop); } else { throw new PrestaShopException('Invalid product vars'); } } // Set available keywords $params = array(); $params['id'] = $product->id; $params['rewrite'] = (!$alias) ? $product->getFieldByLang('link_rewrite') : $alias; $params['ean13'] = (!$ean13) ? $product->ean13 : $ean13; $params['meta_keywords'] = Tools::str2url($product->getFieldByLang('meta_keywords')); $params['meta_title'] = Tools::str2url($product->getFieldByLang('meta_title')); if ($dispatcher->hasKeyword('product_rule', $id_lang, 'manufacturer', $id_shop)) { $params['manufacturer'] = Tools::str2url($product->isFullyLoaded ? $product->manufacturer_name : Manufacturer::getNameById($product->id_manufacturer)); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'supplier', $id_shop)) { $params['supplier'] = Tools::str2url($product->isFullyLoaded ? $product->supplier_name : Supplier::getNameById($product->id_supplier)); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'price', $id_shop)) { $params['price'] = $product->isFullyLoaded ? $product->price : Product::getPriceStatic($product->id, false, null, 6, null, false, true, 1, false, null, null, null, $product->specificPrice); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'tags', $id_shop)) { $params['tags'] = Tools::str2url($product->getTags($id_lang)); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'category', $id_shop)) { $params['category'] = (!is_null($product->category) && !empty($product->category)) ? Tools::str2url($product->category) : Tools::str2url($category); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'reference', $id_shop)) { $params['reference'] = Tools::str2url($product->reference); } if ($dispatcher->hasKeyword('product_rule', $id_lang, 'categories', $id_shop)) { $params['category'] = (!$category) ? $product->category : $category; $cats = array(); foreach ($product->getParentCategories($id_lang) as $cat) { if (!in_array($cat['id_category'], Link::$category_disable_rewrite)) { //remove root and home category from the URL $cats[] = $cat['link_rewrite']; } } $params['categories'] = implode('/', $cats); } $anchor = $ipa ? $product->getAnchor((int)$ipa, (bool)$add_anchor) : ''; return $url.$dispatcher->createUrl('product_rule', $id_lang, $params, $force_routes, $anchor, $id_shop); } Quick search , regular search and Layered navigation works well with this changes. I'll change this thread to solved, thank you . Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now