Post by SSJ » Wed Feb 03, 2010 9:13 pm

问题:
搜索产品时,有时同一产品会重复。
原因:
产品分类系统的问题。当一个产品同时属于多个分类时,就会出现重复。从DEMO看好像是进行不分类搜索时一级分类重复,但通过分析程序和试验,二级分类同样存在这个问题,并且更复杂(一级分类和所属二级分类的关联检索设计和机制有问题)。
解决方案:
最好的解决方案当然是伟大的Daniel继续完善这些漂亮的代码。这里提出一种修补方案,通过对检索结果进行过滤,获得没有重复的记录集。
方法:
修改位于controller/model/product.php的两个函数:getTotalProductsByKeyword()和 getProductsByKeyword()。

getTotalProductsByKeyword()

Code: Select all

	public function getTotalProductsByKeyword($keyword, $category_id = 0, $description = FALSE) {
		if ($keyword) {
			$sql = "SELECT DISTINCT p.product_id FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
			
			if (!$description) {
				$sql .= " AND pd.name LIKE '%" . $this->db->escape($keyword) . "%'";
			} else {
				$sql .= " AND (pd.name LIKE '%" . $this->db->escape($keyword) . "%' OR pd.description LIKE '%" . $this->db->escape($keyword) . "%')";
			}

			if ($category_id) {
				$data = array();
				
				$this->load->model('catalog/category');
				
				$string = rtrim($this->getPath($category_id), ',');
				
				foreach (explode(',', $string) as $category_id) {
					$data[] = "p2c.category_id = '" . (int)$category_id . "'";
				}
				
				$sql .= " AND (" . implode(" OR ", $data) . ")";
			}
			
			$sql .= " AND p.status = '1' AND p.date_available <= NOW()";
			$sql = "SELECT COUNT(*) AS total FROM (" . $sql . ") as un";

			$query = $this->db->query($sql);
		
			if ($query->num_rows) {
				return $query->row['total'];	
			} else {
				return 0;
			}
		} else {
			return 0;	
		}		
	}
getProductsByKeyword()

Code: Select all

	public function getProductsByKeyword($keyword, $category_id = 0, $description = FALSE, $sort = 'pd.name', $order = 'ASC', $start = 0, $limit = 20) {
		if ($keyword) {
		$sql = "SELECT p.*, pd.name AS name, m.name AS manufacturer, ss.name AS stock, (SELECT AVG(r.rating) FROM " . DB_PREFIX . "review r WHERE p.product_id = r.product_id GROUP BY r.product_id) AS rating FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN " . DB_PREFIX . "stock_status ss ON (p.stock_status_id = ss.stock_status_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND ss.language_id = '" . (int)$this->config->get('config_language_id') . "'";
			
			if (!$description) {
				$sql .= " AND pd.name LIKE '%" . $this->db->escape($keyword) . "%'";
			} else {
				$sql .= " AND (pd.name LIKE '%" . $this->db->escape($keyword) . "%' OR pd.description LIKE '%" . $this->db->escape($keyword) . "%')";
			}
			
			if ($category_id) {
				$data = array();
				
				$this->load->model('catalog/category');
				
				$string = rtrim($this->getPath($category_id), ',');
				
				foreach (explode(',', $string) as $category_id) {
					$data[] = "p2c.category_id = '" . (int)$category_id . "'";
				}
				
				$sql .= " AND (" . implode(" OR ", $data) . ")";
			}
		
			$sql .= " AND p.status = '1' AND p.date_available <= NOW()";
			$sql = "(" . $sql . ") as un";

			$sort = preg_replace('/.*\./' , 'un.' , '.' . $sort);	
			if ($sort) {
				$sql .= " ORDER BY " . $sort;
			} else {
				$sql .= " ORDER BY un.name";	
			}
			
			if ($order == 'DESC') {
				$sql .= " DESC";
			} else {
				$sql .= " ASC";
			}

			if ($start < 0) {
				$start = 0;
			}
		
			$sql .= " LIMIT " . (int)$start . "," . (int)$limit;
			$sql = "SELECT DISTINCT * FROM " . $sql;

			$query = $this->db->query($sql);
		
			return $query->rows;
		} else {
			return 0;	
		}
	}
类似的问题在“产品分类”频道也有,只是没有进行一二级分类关联,从而漏检,但如果关联,会遇到同样的问题。
可以如法炮制试试。
SSJ

SSJ
Newbie

Posts

Joined
Wed Feb 03, 2010 1:05 am

Post by SSJ » Thu Feb 04, 2010 11:11 am

更正:上面两段代码是在:
catalog/model/catalog/product.php
是修改后的,大约有十几个地方有改动,并在本地进行了运行验证,仅供有编程经验者参考,还望高手指点。像类似这样的问题,我想opencart在以后肯定会从系统角度圆满解决。

SSJ
Newbie

Posts

Joined
Wed Feb 03, 2010 1:05 am

Post by twei » Thu Feb 04, 2010 8:46 pm

看来楼主对Opencart 很熟练。是否出一个支付宝的支付插件呢? 期待!

New member

Posts

Joined
Mon Dec 21, 2009 2:12 am

Post by pppoe2299 » Fri Mar 19, 2010 6:29 am

還在想辬法時就找到樓主的解決法........ O0
樓主真強.... >:D
謝謝樓主

Newbie

Posts

Joined
Fri Mar 19, 2010 6:24 am
Who is online

Users browsing this forum: Baidu [Spider] and 4 guests