I have a strongly modified opencart store.
I would like to display all products from subcategories on the main category pages. This is the half-done code from my product model file.
} else {
$cat_sql = "SELECT `category_id` FROM `" . DB_PREFIX . "category_path` WHERE `path_id` = '" . (int)$data['filter_category_id'] . "'";
$cat_query = $this->db->query($cat_sql);
if ($cat_query->num_rows) {
$sql .= " AND (p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
foreach($cat_query->rows as $cat) {
$sql .= " OR p2c.category_id = '" . (int)$cat['category_id'] . "'";
}
$sql .= ")";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
}
}
It's supposed to display those products.
But now I have another table for multiple parent categories.
My question is: how can I display the products from the subcategories, where I just have parent_id not path_id.
The multiple category table is simple.
category_id / parent_id
How can I modify the code above so that it displays all products from subcategories where they don't have path_id only parent_id?
You dont need to modify sql just pass extra parameter 'filter_sub_category' => true and it will list out all the product including child category
$filter_data = array(
'filter_category_id' => $category_id,
'filter_sub_category' => true
);
$results = $this->model_catalog_product->getProducts($filter_data);
Related
Products on my shop now have URLs like this:
example.com/category1/product1
or
example.com/category1/subcategory1/product1
and it's one and the same product only assigned into 2 categories. URL depends on if you go from cateogry1 or subcategory1.
I want to force opencart to always go to example.com/category1/subcategory1/product1 (the deepest subcategory).
Do you know how to do it? I didn't find any extension for it. I'm gonna probably have to change /catalog/controller/common/seo_url.php but I'm not sure what to change and I don't wanna brake it.
I'm running on OpenCart 1.5.6.
Go to admin panel and open category form and remove the seo keywords for the category and the subcategory.
Then you will get full path of the category.
You need to add some code to do this without extension.
In controller/seo_url.php add this function
public function getFullProductPath($product_id) {
$path = array();
$categories = $this->db->query("SELECT c.category_id, c.parent_id FROM " . DB_PREFIX . "product_to_category p2c LEFT JOIN " . DB_PREFIX . "category c ON (p2c.category_id = c.category_id) WHERE product_id = '" . (int)$product_id . "'")->rows;
foreach($categories as $key => $category)
{
$path[$key] = '';
if (!$category) continue;
$path[$key] = $category['category_id'];
while ($category['parent_id']){
$path[$key] = $category['parent_id'] . '_' . $path[$key];
$category = $this->db->query("SELECT category_id, parent_id FROM " . DB_PREFIX . "category WHERE category_id = '" . $category['parent_id']. "'")->row;
}
$path[$key] = $path[$key];
}
if (!count($path)) return '';
// wich one is the largest ?
$whichone = array_map('strlen', $path);
asort($whichone);
$whichone = array_keys($whichone);
$whichone = array_pop($whichone);
return $path[$whichone];
}
I'm using OpenCart ecommerce, and I would like to see in the index of ecommerce the total number of products
I do not have (for now) access to the db opencart, so to understand what is the structure of the db I have referred to this image
And this is an example of a query that I'm trying to use to display the total number of products (the result is obviously not what I expect)
//Test Count Product
//$query_test = $db->query("SELECT " . DB_PREFIX . "product_description.name FROM " . DB_PREFIX . "product INNER JOIN " . DB_PREFIX . "product_description ON " . DB_PREFIX . "product.product_id = " . DB_PREFIX . "product_description.product_id");
$query_test = $db->query("SELECT * FROM " . DB_PREFIX . "product");
$count_test = 0;
foreach ($query_test as $row) {
$count_test++;
}
echo $count_test;
Try this:
$query = $db->query("SELECT COUNT(*) AS total FROM ".DB_PREFIX."product");
echo $query->row['total'];
Nicolo,
Your code is also correct. For that you need to use this code
$query_test = $db->query("SELECT * FROM " . DB_PREFIX . "product");
$count_test = 0;
foreach ($query_test->rows as $row) {
$count_test++;
}
echo $count_test;
But, I will recommend Monkeyman's way to get product_totals but with some modification (Monkeyman's code will NOT work for multiple stores)
$query = $db->query("SELECT COUNT(*) AS total FROM ".DB_PREFIX."product_to_store WHERE store_id = '" . (int)$this->config->get('config_store_id') . "'");
echo $query->row['total'];
well, im trying to get the shipping cost for each product but i have no idea to get the shipping cost correctly, example on my product_shipping_cost table
product_id, shipping_cost
1, 12
2, 15
etc.....
now i try to get single product shipping_cost using this query
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_shipping_cost WHERE product_id='" . (int)$product_id . "'");
$cost = $query->row['shipping_cost'];
yes, i got the shipping cost perfectly! but what if i want to get two or more shipping cost? i mean sum the shipping_cost with the selected product_id so it would be 12+15=27 shipping cost, i use this with no luck..
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_shipping_cost WHERE product_id='" . (int)$product_id . "'");
foreach($query->row as $shipping) {
$cost = $shipping['shipping_cost'];
}
any ideas?
$cost needs to be an array for it to store multiple costs unless you plan on using it in the for loop. ie..
$costTotal = 0;
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_shipping_cost");
foreach($query->row as $shipping) {
$costTotal += $shipping['shipping_cost'];
}
updated to reflect op comment.
Add the costs in your query:
$query = $this->db->query("SELECT SUM(shipping_cost) total_shipping FROM " . DB_PREFIX . "product_shipping_cost WHERE product_id='" . (int)$product_id . "'");
$cost = $query->row['total_shipping'];
done by using this code
$total = 0;
foreach ($this->cart->getProducts() as $product) {
$product_id = $product['product_id'];
$query = $this->db->query("SELECT shipping_cost FROM " . DB_PREFIX . "product_shipping_cost WHERE product_id='" . (int)$product_id . "'");
$total += $query->row['shipping_cost'];
$cost = $total;
}
but still will return an error if the shipping_cost for the product is not set in the database
I am really struggling on how to achieve this and hope that someone can help me. I have the existing function and query:
public function setStockAndPrice($product_id) {
$query = $this->db->query('UPDATE ' . DB_PREFIX . 'product SET quantity = 0, price = 0.00 WHERE product_id = ' . (int)$product_id)
}
This works, but it sets all products to Zero when I actually want it to only set products to Zero when that product exists in another table.
i.e., in explanatory terms:
public function setStockAndPrice($product_id) {
$query = $this->db->query('UPDATE ' . DB_PREFIX . 'product SET quantity = 0, price = 0.00 WHERE product_id = ' . (int)$product_id AND product_id exists in CustomerProducts)
}
I am not au fait with joins, but I am not sure if I even need to use a join here as the query seems more simple than that.
Can anyone point me in the right direction?
public function setStockAndPrice($product_id) {
$query = $this->db->query('UPDATE ' . DB_PREFIX . 'product SET quantity = 0, price = 0.00 WHERE product_id = ' . (int)$product_id ." AND product_id =(select DISTINCT(product_id) from CustomerProducts where product_id= $product_id)" )
}
This may work.
use this will work for you are not assigning db.product and make sure you write query in a string then execute.
And you see you query, by removing comments
public function setStockAndPrice($product_id) {
$query_string = "UPDATE " . DB_PREFIX . ".product SET quantity = '0', price = '0.00' WHERE product_id = '$product_id'";
// echo "Query : " . $query_string;
$query = $this->db->query($query_string);
}
public function setStockAndPrice($product_id) {
$query = $this->db->query('UPDATE ' . DB_PREFIX . '.product p, ' . DB_PREFIX . '.CustomerProducts cp SET p.quantity = 0, p.price = 0.00 WHERE p.product_id = ' . (int)$product_id . ' AND p.product_id = cp.product_id');
}
I am trying to make dynamic product filtering for opencart in which user could add filters, assign them to categories and assign filter values for products.
Currently I Have these mysql tables:
Filters - ID NAME
Filters_categories - ID FILTER_ID CATEGORY_ID
Filters_values - ID FILTER_ID VALUE
Filters_products - ID FILTER_ID VALUE_ID PRODUCT_ID
The problem is with this structure that i can't get products when more than one filter is activated because i get MySQL query which looks something like this:
SELECT product_id FROM Filters_products WHERE ((name_id='1' OR name_id='2') AND filter_id='1') AND ((name_id='3' OR name_id='4') AND filter_id='2')
And it doesn't make any sense. I can't figure out how should i change my database structure to make dynamic filtering possible. How can I solve this situation?
Thank you.
SELECT product_id FROM Filters_products WHERE (screen_id='1' OR screen_id='2') and (connection_id='1')
Use this awesome extension,
http://www.opencart.com/index.php?route=extension/extension/info&extension_id=10098
Hope this helps.
in file /catalog/model/catalog/product.php find line nr. 91 and replace "if {}" block whit this code...
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) {
$filterSQL = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter WHERE filter_id = ". $filter_id);
$implode[$filterSQL->row['filter_group_id']][] = (int)$filter_id;
}
foreach($implode AS $implode2) {
$sql .= " AND (";
foreach($implode2 AS $filterID) {
$sql .= "(SELECT count(*) FROM product_filter WHERE product_filter.product_id=p.product_id AND product_filter.filter_id=$filterID) OR ";
}
$sql = substr($sql, 0, -4);
$sql .= ")";
}
}
}