I have a two piece of code for Regions and Categories. They are exactly the same. The code for Category works, but "Region" returns the following error:
Fatal error: Call to a member function getRegion() on null in C:\wamp64\www\site\catalog\controller\module\latest.php on line 81
// Region
$product_region = array();
$regions = $this->model_profile_profile->getProductRegions($result['product_id']);
foreach ($regions as $region_id) {
print_r($region_id); // !!! ($region_id = 2) !!! $region_id is not empty !!!
$region_info = $this->model_account_region->getRegion($region_id); // LINE 81
if ($region_info) {
$product_region[] = array(
'name' => ($region_info['path']) ? $region_info['path'] . ' > ' . $region_info['name'] : $category_info['name'],
'href' => $this->url->link('account/profile', '&path=' . $region_info['region_id'])
);
}
}
And here is the code which probably causes the error:
public function getRegion($region_id) {
$query = $this->db->query("SELECT DISTINCT *, (SELECT GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR ' > ') FROM " . DB_PREFIX . "region_path cp LEFT JOIN " . DB_PREFIX . "region_description cd1 ON (cp.path_id = cd1.region_id AND cp.region_id != cp.path_id) WHERE cp.region_id = c.region_id AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY cp.region_id) AS path, (SELECT DISTINCT keyword FROM " . DB_PREFIX . "url_alias WHERE query = 'region_id=" . (int)$region_id . "') AS keyword FROM " . DB_PREFIX . "region c LEFT JOIN " . DB_PREFIX . "region_description cd2 ON (c.region_id = cd2.region_id) WHERE c.region_id = '" . (int)$region_id . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'");
return $query->row;
}
I'd appreciate if you help me by giving a piece of code, because I'm dummy in PHP.
$this->model_account_region //This property is null
Check
echo 'FILE : '.__FILE__ .'<br/>';
echo 'LINE : '.__LINE__ .'<br/>';
echo '<pre>';
var_dump( empty( $this->model_account_region ) );
echo '</pre>';
exit;
model_account_region model class is messed up. Since you are running out of time. I suggest you copy the function
public function getRegion($region_id) {
$query = $this->db->query("SELECT DISTINCT *, (SELECT GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR ' > ') FROM " . DB_PREFIX . "region_path cp LEFT JOIN " . DB_PREFIX . "region_description cd1 ON (cp.path_id = cd1.region_id AND cp.region_id != cp.path_id) WHERE cp.region_id = c.region_id AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY cp.region_id) AS path, (SELECT DISTINCT keyword FROM " . DB_PREFIX . "url_alias WHERE query = 'region_id=" . (int)$region_id . "') AS keyword FROM " . DB_PREFIX . "region c LEFT JOIN " . DB_PREFIX . "region_description cd2 ON (c.region_id = cd2.region_id) WHERE c.region_id = '" . (int)$region_id . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'");
return $query->row;
}
into model_profile_profile then call it from there ie
$region_info = $this->model_profile_profile->getRegion($region_id); // LINE 81
if that fails its the db class failing to load properly so you add this line before calling your function on line 81
$this->load->database();
let me know if you are facing more challenges. I am a bit bored over here.
Related
I'm having this error when click on a tag on product page on my Opencart 2.3.0.2 store
PHP Fatal error: Uncaught exception 'Exception' with message 'Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'OR man.name LIKE '%%' pd.tag LIKE '%conjunto%' AND pd.tag LIKE '%infantil%' AND ' at line 1<br />Error No: 1064<br />SELECT p.product_id, (SELECT AVG(rating) AS total FROM oc_review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT price FROM oc_product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '1' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM oc_product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '1' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priori in C:\inetpub\wwwroot\cabanins\system\library\db\mysqli.php on line 40
I dont know what the reason for this error is because my localhost version is working normally.
Your issue is right here:
man.name LIKE '%%' pd.tag
You need to include a AND tag like so
man.name LIKE '%%' AND pd.tag
Although there's no reason to have
man.name LIKE '%%'
as %% will match EVERYTHING.
So you could just make it:
OR pd.tag LIKE '%conjunto%'
Thanks for helping me. I dont understand why the code is wrong only on online version and works fine on localhost. Im using the same code. Thats the code
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (cp.category_id = p2c.category_id)";
} else {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c";
}
if (!empty($data['filter_filter'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_filter pf ON (p2c.product_id = pf.product_id) LEFT JOIN ".$from." p ON (pf.product_id = p.product_id)";
} else {
$sql .= " LEFT JOIN ".$from." p ON (p2c.product_id = p.product_id)";
}
} else {
$sql .= " FROM ".$from." p";
}
$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '" . (int) $this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int) $this->config->get('config_store_id') . "'";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " AND cp.path_id = '" . (int) $data['filter_category_id'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int) $data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$implode[] = (int) $filter_id;
}
$sql .= " AND pf.filter_id IN (" . implode(',', $implode) . ")";
}
}
if (!empty($data['filter_name']) || !empty($data['filter_tag'])) {
$sql .= " AND (";
if (!empty($data['filter_name'])) {
$implode = array();
$words = explode(' ', trim(preg_replace('/\s+/', ' ', $data['filter_name'])));
foreach ($words as $word) {
$implode[] = "pd.name LIKE '%" . $this->db->escape($word) . "%'";
}
if ($implode) {
$sql .= " " . implode(" AND ", $implode) . "";
}
if (!empty($data['filter_description'])) {
$sql .= " OR pd.description LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
}
}
if (!empty($data['filter_name']) && !empty($data['filter_tag'])) {
$sql .= " OR ";
}
if (!empty($data['filter_tag'])) {
$implode = array();
$words = explode(' ', trim(preg_replace('/\s+/', ' ', $data['filter_tag'])));
foreach ($words as $word) {
$implode[] = "pd.tag LIKE '%" . $this->db->escape($word) . "%'";
}
if ($implode) {
$sql .= " " . implode(" AND ", $implode) . "";
}
}
if (!empty($data['filter_name'])) {
if($multiplicar_produtos) {
$sql .= " OR LCASE(p.model) LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "%'";
} else {
$sql .= " OR LCASE(p.model) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
$sql .= " OR LCASE(p.sku) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.upc) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.ean) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.jan) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.isbn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.mpn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
$sql .= ")";
}
I am using OC 2.2.0 and been struggling with the following problem for a while now:
Example: I enter Siemens in header search and click SHOW ALL RESULTS, my search page appears with all results. The problem is - results list includes only products that have Siemens in their NAME. What I need is to show all products in search results list, belonging to that manufacturer, which in our example is Siemens manufacturer. In my search.php controller file, results are defined in this line:
$results = $this->model_catalog_product->getProducts($filter_data);
Which shows me that getProducts($filter_data) function of product.php file in model-catalog-product is where I need to define results. I tried tweaking the query in this function so that it includes manufacturer in search results too, but with no luck. So far, my getProducts($filter_data) function looks like this:
public function getProducts($data = array()) {
$sql = "SELECT p.product_id, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
if(!empty($data['filter_sub_subcategory'])) {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c";
} else {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c";
}
//$sql .= " FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (cp.category_id = p2c.category_id)";
} else {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c LEFT JOIN " . DB_PREFIX . "category cc ON (p2c.category_id = cc.category_id)";
}
if (!empty($data['filter_filter'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_filter pf ON (p2c.product_id = pf.product_id) LEFT JOIN " . DB_PREFIX . "product p ON (pf.product_id = p.product_id)";
} else {
$sql .= " LEFT JOIN " . DB_PREFIX . "product p ON (p2c.product_id = p.product_id)";
}
} else {
$sql .= " FROM " . DB_PREFIX . "product p";
}
$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
if(!empty($data['filter_sub_subcategory'])) {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_sub_subcategory'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_sub_category'] . "'";
}
//$sql .= " AND cp.path_id = '" . (int)$data['filter_category_id'] . "'";
} else {
$sql .= " AND cc.parent_id = '" . (int)$data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$implode[] = (int)$filter_id;
}
$sql .= " AND pf.filter_id IN (" . implode(',', $implode) . ")";
}
}
if (!empty($data['filter_subcategory_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_sub_category'] . "'";
//$sql .= " AND cp.path_id = '" . (int)$data['filter_category_id'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$implode[] = (int)$filter_id;
}
$sql .= " AND pf.filter_id IN (" . implode(',', $implode) . ")";
}
}
if (!empty($data['filter_sub_subcategory'])) {
if (!empty($data['filter_sub_subcategory'])) {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_sub_subcategory'] . "'";
//$sql .= " AND cp.path_id = '" . (int)$data['filter_category_id'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$implode[] = (int)$filter_id;
}
$sql .= " AND pf.filter_id IN (" . implode(',', $implode) . ")";
}
}
if (!empty($data['filter_name']) || !empty($data['filter_tag'])) {
$sql .= " AND (";
if (!empty($data['filter_name'])) {
$implode = array();
$words = explode(' ', trim(preg_replace('/\s+/', ' ', $data['filter_name'])));
foreach ($words as $word) {
$implode[] = "pd.name LIKE '%" . $this->db->escape($word) . "%'";
}
if ($implode) {
$sql .= " " . implode(" AND ", $implode) . "";
}
if (!empty($data['filter_description'])) {
$sql .= " OR pd.description LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
}
}
if (!empty($data['filter_name']) && !empty($data['filter_tag'])) {
$sql .= " OR ";
}
if (!empty($data['filter_tag'])) {
$sql .= "pd.tag LIKE '%" . $this->db->escape($data['filter_tag']) . "%'";
}
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.model) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.sku) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.upc) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.ean) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.wholesale) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.isbn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.mpn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
$sql .= ")";
}
if (!empty($data['filter_manufacturer_id'])) {
$sql .= " AND p.manufacturer_id = '".(int)$data['filter_manufacturer_id']."'";
}
$sql .= " GROUP BY p.product_id";
$sort_data = array(
'pd.name',
'p.model',
'p.quantity',
'p.price',
'rating',
'p.sort_order',
'p.date_added'
);
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
$sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
} elseif ($data['sort'] == 'p.price') {
$sql .= " ORDER BY (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
} else {
$sql .= " ORDER BY " . $data['sort'];
}
} else {
$sql .= " ORDER BY p.sort_order";
}
if (isset($data['order']) && ($data['order'] == 'DESC')) {
$sql .= " DESC, LCASE(pd.name) DESC";
} else {
$sql .= " ASC, LCASE(pd.name) ASC";
}
if (isset($data['start']) || isset($data['limit'])) {
if ($data['start'] < 0) {
$data['start'] = 0;
}
if ($data['limit'] < 1) {
$data['limit'] = 20;
}
$sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
}
$product_data = array();
$query = $this->db->query($sql);
foreach ($query->rows as $result) {
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
return $product_data;
}
Can anyone help tweak the query so that it can show all products belonging to a searched manufacturer?
Thank you in advance.
So, finally i realized what was the missing query. Before the line
$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON
(p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX .
"product_to_store p2s
I had to put $sql .= " LEFT JOIN " . DB_PREFIX . "manufacturer m ON (m.manufacturer_id = p.manufacturer_id) ";
And then just before the line
$sql .= " OR LCASE(p.model) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
I had to put
$sql .= " OR LCASE(m.name) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
So obviously I was missing the manufacturer data. This way I pulled the data from manufacturer table and processed it correctly. I hope this helps someone, cheers!
ORDER BY is not working. I've tried ways I know but it won't order by, why?
returns : Call to a member function result_array() on boolean
public function getDetailbyClsandSection($class_id, $section_id, $exam_id) {
$query = $this->db->query("SELECT exam_schedules.*,subjects.name,subjects.type FROM exam_schedules,teacher_subjects,exams,class_sections,subjects WHERE exam_schedules.teacher_subject_id = teacher_subjects.id and exam_schedules.exam_id =exams.id and class_sections.id =teacher_subjects.class_section_id and teacher_subjects.subject_id=subjects.id and class_sections.class_id =" . $this->db->escape($class_id) . " and class_sections.section_id=" . $this->db->escape($section_id) . " and exam_id =" . $this->db->escape($exam_id) . " and exam_schedules.session_id=" . $this->db->escape($this->current_session));
return $query->result_array();
}
$query = $this->db->query("SELECT exam_schedules.*,subjects.name,subjects.type FROM exam_schedules,teacher_subjects,exams,class_sections,subjects WHERE exam_schedules.hide = 'N' and exam_schedules.teacher_subject_id = teacher_subjects.id and exam_schedules.exam_id =exams.id and class_sections.id =teacher_subjects.class_section_id and teacher_subjects.subject_id=subjects.id and class_sections.class_id =" . $this->db->escape($class_id) . " and class_sections.section_id=" . $this->db->escape($section_id) . " and exam_id =" . $this->db->escape($exam_id) . " and exam_schedules.session_id=" . $this->db->escape($this->current_session) . " ORDER BY exam_schedules.date_of_exam ASC");
I am trying to run query but i am not able to get right output and i am getting this error,i tried some stackoverflow eg. but i not able to resolve it.
--error---
Notice: Error: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near 'LEFT JOIN oc_product_to_manufacturer p2m ON (p.product_id =
p2m.product_id) WHER' at line 1
Error No: 1064
SELECT COUNT(DISTINCT p.product_id) AS total FROM oc_product p LEFT JOIN oc_product_description pd ON (p.product_id =
pd.product_id) LEFT JOIN oc_product_to_store p2s ON (p.product_id =
p2s.product_id) WHERE pd.language_id = '1' AND p.status = '1' AND
p.date_available <= NOW() AND p2s.store_id = '0' LEFT JOIN
oc_product_to_manufacturer p2m ON (p.product_id = p2m.product_id)
WHERE p2m.manufacturer_id = '8'
the total code which in which the issue is
public function getTotalProducts($data = array()) {
$sql = "SELECT COUNT(DISTINCT p.product_id) AS total";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (cp.category_id = p2c.category_id)";
} else {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c";
}
if (!empty($data['filter_filter'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_filter pf ON (p2c.product_id = pf.product_id) LEFT JOIN " . DB_PREFIX . "product p ON (pf.product_id = p.product_id)";
} else {
$sql .= " LEFT JOIN " . DB_PREFIX . "product p ON (p2c.product_id = p.product_id)";
}
} else {
$sql .= " FROM " . DB_PREFIX . "product p";
}
$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " AND cp.path_id = '" . (int)$data['filter_category_id'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$implode[] = (int)$filter_id;
}
$sql .= " AND pf.filter_id IN (" . implode(',', $implode) . ")";
}
}
if (!empty($data['filter_name']) || !empty($data['filter_tag'])) {
$sql .= " AND (";
if (!empty($data['filter_name'])) {
$implode = array();
$words = explode(' ', trim(preg_replace('/\s+/', ' ', $data['filter_name'])));
foreach ($words as $word) {
$implode[] = "pd.name LIKE '%" . $this->db->escape($word) . "%'";
}
if ($implode) {
$sql .= " " . implode(" AND ", $implode) . "";
}
if (!empty($data['filter_description'])) {
$sql .= " OR pd.description LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
}
}
if (!empty($data['filter_name']) && !empty($data['filter_tag'])) {
$sql .= " OR ";
}
if (!empty($data['filter_tag'])) {
$sql .= "pd.tag LIKE '%" . $this->db->escape(utf8_strtolower($data['filter_tag'])) . "%'";
}
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.model) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.sku) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.upc) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.ean) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.jan) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.isbn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
$sql .= " OR LCASE(p.mpn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
$sql .= ")";
}
/* if (!empty($data['filter_manufacturer_id'])) {
$sql .= " AND p.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";
}*/
/* if (!empty($data['filter_manufacturer_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_manufacturer p2m ON (p2m.product_id = p.product_id) WHERE p2m.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";*/
if (!empty($data['filter_manufacturer_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_manufacturer p2m ON (p.product_id = p2m.product_id) WHERE p2m.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";
}
$query = $this->db->query($sql);
return $query->row['total'];
}
this the main code which making the error
if (!empty($data['filter_manufacturer_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_manufacturer p2m
ON (p.product_id = p2m.product_id)
WHERE p2m.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";
}
You have mixed ON and WHERE near the line that threw the error. Change your query to look like this:
SELECT COUNT(DISTINCT p.product_id) AS total
FROM oc_product p
LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id)
LEFT JOIN oc_product_to_store p2s ON (p.product_id = p2s.product_id)
AND pd.language_id = '1' AND p.status = '1'
AND p.date_available <= NOW() AND p2s.store_id = '0'
LEFT JOIN oc_product_to_manufacturer p2m ON (p.product_id = p2m.product_id)
AND p2m.manufacturer_id = '8'
I want to add a new tab into the products page allowing logged in customers to directly download from product page.
At first this seems simple, but it seems that opencart is missing the download_id from order_download table so maybe I am doing this all wrong.
UPDATE: Been doing some digging into the admin and find that opencart is actually using the filename instead of download_id so guess I will have to use that. E.g:
$this->db->query("UPDATE " . DB_PREFIX . "order_download SET `filename` = '" . $this->db->escape($data['filename']) . "', mask = '" . $this->db->escape($data['mask']) . "', remaining = '" . (int)$data['remaining'] . "' WHERE `filename` = '" . $this->db->escape($download_info['filename']) . "'");
The updated method below so am I doing this correct? Seems a lot of queries so not sure if this can be improved?
public function getProductDownloads($product_id) {
$data = array();
$result = $this->db->query("SELECT download_id FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
foreach ($result->rows as $product_download) {
$product_download_query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "download d LEFT JOIN " . DB_PREFIX . "download_description dd ON (d.download_id = dd.download_id) WHERE d.download_id = '" . (int)$product_download['download_id'] . "' AND dd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
foreach ($product_download_query->rows as $download) {
if (!file_exists(DIR_DOWNLOAD . $download['filename'])) continue;
$row = array(
'download_id' => $download['download_id'],
'date_added' => date($this->language->get('date_format_short'), strtotime($download['date_added'])),
'name' => $download['name'],
'href' => ''
);
if($this->customer->isLogged()){
// 1. Get customer orders
$order_download_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_download od LEFT JOIN `" . DB_PREFIX . "order` o ON (od.order_id = o.order_id) WHERE o.customer_id = '" . (int)$this->customer->getId(). "' AND o.order_status_id > '0' AND o.order_status_id = '" . (int)$this->config->get('config_complete_status_id') . "' AND (od.remaining = -1 OR od.remaining > 0) AND od.filename = '" . $this->db->escape($download['filename']) . "'");
foreach($order_download_query->rows as $order_download) {
// 2. Check customer ordered product
$order_product_download_query = $this->db->query("SELECT 1 FROM " . DB_PREFIX . "order_product op WHERE op.order_product_id = '" . (int)$order_download['order_product_id']. "' AND op.product_id = '" . (int)$product_id . "'");
if($order_product_download_query->row) {
$row['href'] = $this->url->link('account/download/download', 'order_download_id=' . $order_download['order_download_id'], 'SSL');
$row['remaining'] = $order_download['remaining'];
break;
}
}
}
$data[] = $row;
}
}
return $data;
}
First You don't have to run update query, after Placing order it adds data
see /catalog/model/checkout/order.php::addOrder()
To download files
Product Must have download File
Order Status should be Complete
Download remaining should be more than 0
see /catalog/model/account/download.php::getDownloads()
Solution
add following code after if ($product_info) { around line 170 of /catalog/controller/product/product.php
if ($this->customer->isLogged()) {
$this->load->model('account/download');
$results = $this->model_account_download->getDownloadByProduct($product_id);
foreach ($results as $result) {
if (file_exists(DIR_DOWNLOAD . $result['filename'])) {
$size = filesize(DIR_DOWNLOAD . $result['filename']);
$i = 0;
$suffix = array(
'B',
'KB',
'MB',
'GB',
'TB',
'PB',
'EB',
'ZB',
'YB'
);
while (($size / 1024) > 1) {
$size = $size / 1024;
$i++;
}
$this->data['downloads'][] = array(
'order_id' => $result['order_id'],
'name' => $result['name'],
'remaining' => $result['remaining'],
'size' => round(substr($size, 0, strpos($size, '.') + 4), 2) . $suffix[$i],
'href' => $this->url->link('account/download/download', 'order_download_id=' . $result['order_download_id'], 'SSL')
);
}
}
}
Default download method fetches all downloads by customer but we need downloads on product by customer
so /catalog/model/account/download.php add new function. This will fetch associated downloads of product if customer have remaining download of that product.
public function getDownloadByProduct($product_id) {
$query = $this->db->query("SELECT o.order_id, o.date_added, od.order_download_id, od.name, od.filename, od.remaining FROM " . DB_PREFIX . "order_download od LEFT JOIN `" . DB_PREFIX . "order` o ON (od.order_id = o.order_id) LEFT JOIN `" . DB_PREFIX . "order_product` op ON (o.order_id = op.order_id) WHERE o.customer_id = '" . (int)$this->customer->getId() . "' AND o.order_status_id > '0' AND o.order_status_id = '" . (int)$this->config->get('config_complete_status_id') . "' AND od.remaining > 0 AND op.product_id = ' " . $product_id . " ' ORDER BY o.date_added DESC");
return $query->rows;
}
now in product.tpl file you can echo download
<?php
if(isset($downloads)){
foreach ($downloads as $download) { ?>
<?php echo $download['name'].'('.$download['remaining'].')' ?>
<?php }
}
?>
Hope This helps