I'm trying to get "product_id" by "customer_id", but don't know how to do it:
public function getProductId($customer_id) {
$query = $this->db->query("SELECT DISTINCT product_id FROM " . DB_PREFIX . "product p WHERE p.customer_id = '" . (int)$customer_id . "'");
if ($query->num_rows) {
$data = $query->row;
return $product_id;
}
}
Related
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");
Using a custom template (Journal 2) for a PHP-based E-commerce system.
In the control panel, there's a section that loads custom modules.
Problem is, the modules are presented in the order of creation, which makes it hard to find the right module.
I would like to sort them alphabetically.
How & where can I add a sort-by-name feature to this function?
public function all() {
if (isset($this->get_data['module_type'])) {
$module_type = $this->db->escape('journal2_' . $this->get_data['module_type']);
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules WHERE module_type = "' . $module_type . '"');
} else {
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules');
}
foreach ($query->rows as &$row) {
$row['module_data'] = json_decode($row['module_data'], true);
if (is_array($row['module_data'])) {
foreach($row['module_data'] as $key => &$value) {
if (!in_array($key, array('module_name', 'module_type'))) {
unset($row['module_data'][$key]);
}
}
}
}
return $query->rows;
}
Thanks in advance!
If you need an specific order, in sql you can use the order by clause. In your case could be useful order by module_name
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX .
'journal2_modules WHERE module_type = "' .
$module_type . '" order by module_name ');
Try altering your query:
if (isset($this->get_data['module_type'])) {
$module_type = $this->db->escape('journal2_' . $this->get_data['module_type']);
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules WHERE module_type = "' . $module_type . '" ORDER BY module_data ASC');
} else {
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules ORDER BY module_data ASC');
}
At the end of your queries insert an ORDER BY condition like ORDER BY columnName to sort by that column.
public function all() {
if (isset($this->get_data['module_type'])) {
$module_type = $this->db->escape('journal2_' . $this->get_data['module_type']);
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules WHERE module_type = "' . $module_type . '"' . ' ORDER BY ' . $this->get_data['module_order_by']);
} else {
$query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'journal2_modules ORDER BY ' . $this->get_data['module_order_by']);
}
foreach ($query->rows as &$row) {
$row['module_data'] = json_decode($row['module_data'], true);
if (is_array($row['module_data'])) {
foreach($row['module_data'] as $key => &$value) {
if (!in_array($key, array('module_name', 'module_type'))) {
unset($row['module_data'][$key]);
}
}
}
}
return $query->rows;
}
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.
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