Open cart 1.5.6 select description rule - php

I am trying to do one change in opencart source code (1.5.6 version), but unfortunately without success.
We have 5 languages on website with descriptions.
I want to show english description for the products on all version of languages on web site (on the page: ?route=product/product&product_id=X)
All other content will be on selected language but only description need be on english (no matter what language is selected).
I am searching for solution, and only logical for me is that this changes in code need to be make on product.php file under catalog/controller/product dir.
But can anybody give to me advice where to change the line of code where open cart select language id? In database english is language_id = 1
Maybe I can do this
remove this line on product.tpl
<div id="tab-description" class="tab-content"><?php echo $description; ?></div>
and put something like this, but how select description in this case
<div id="tab-description" class="tab-content"><?php SELECT DESCRIPTION FROM DATABASE WHERE LANGUAGE_ID =1 ?></div>

Mainly you need to modify your Model, Controller and View files:
Open you product model file from here : catalog/model/catalog/product.php
Add following code before line no 64 or public function getProducts($data = array()) {
public function getProductEngDesc($product_id) {
$query = $this->db->query("SELECT DISTINCT * 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_store p2s ON (p.product_id = p2s.product_id) WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '1' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
if ($query->num_rows) {
return array(
'description' => $query->row['description'],
);
} else {
return false;
}
}
Open you product Controller file from here : catalog/controller/product/product.php
Add following line after $product_info = $this->model_catalog_product->getProduct($product_id);
$product_eng_desc = $this->model_catalog_product->getProductEngDesc($product_id);
Add following line after $this->data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
$this->data['eng_description'] = html_entity_decode($product_eng_desc['description'], ENT_QUOTES, 'UTF-8');
Now open your Product template file and replace below line
<div id="tab-description" class="tab-content"><?php echo $description; ?></div>
With
<div id="tab-description" class="tab-content"><?php echo $eng_description; ?></div>

Related

Issue is This function shows me same product_id output on related products

The issue is Output on related products it shows on every related product box same total counted number in OpenCart. So, it see just main product_id. So, must indicate related product_id somehow. I tried many many ways but it don`t work for me. Can someone help me to fix this?
There is function on modules:
public function getUnitsSold($product_id) {
$query = $this->db->query("SELECT SUM(op.quantity) AS total FROM `" . DB_PREFIX . "order_product` op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id) WHERE o.order_status_id = '5' AND op.product_id = '" . (int)$product_id . "'");
if ($query->row) {
return $query->row['total'];
} else {
return FALSE;
}
}
And this is simply template output.
<?php if ($tproducts) { ?>
<?php foreach ($tproducts as $product) { ?>
<?php if ($product['units_sold']) { ?>
<?php echo $text_units_sold; ?> <?php echo $product['units_sold']; ?>
<?php } ?>
<?php } ?>
<?php } ?>
In controller where is related product array is a possibility to indicate maybe this function query and then make right output.
something like that units_sold?
$data['tproducts'][] = array(
'product_id' => $result['product_id'],
'units_sold' => $this->db->query("SELECT SUM(op.quantity) AS total FROM `" . DB_PREFIX . "order_product` op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id) WHERE o.order_status_id = '5' AND op.product_id = '" . (int)$product_id . "'"),
);
or maybe
$data['tproducts'][] = array(
'product_id' => $result['product_id'],
'units_sold' => $this->model_catalog_product->getUnitsSold($this->request->get['product_id']),
);
You'll want to store the amount of sold items on the item itself.
Increment the number as if it is a reverse stock.
So, I'd just ALTER TABLE oc_product ADD amount_sold INT(8) NULL DEFAULT NULL;
Then, just display that simple column value. The storage of the orders must be modified and becomes a little bit slower (in the order of .001 - .0001s).
This way the store will keep performing well in the future, even when your order item table has become huge.
Let the storage handler be the working horse. Take a look at ModelCheckoutOrder::addOrderHistory(), when they subtract the quantity, you must add your quantity :)
"UPDATE " . DB_PREFIX . "product SET /*.... opencart default shit */, amount_sold = (amount_sold + " . (int)$order_product['quantity'] . ")

Custom price calculation in prestashop

I'm working on a Prestashop 1.5.x website, where I need to add a custom price-calculation rule for a specific product.
My goal is to add 10 dollars per order, but PS adds extra cost by product quantity, so if you order 20 products it ask you 200$ instead of 10...
I need to override the calculating process in /classes/Product.php, with something like:
if (product_id = 44) { $price = $price + 10; }
else { $price = $price }
Have you got any idea?
You have to create an override of the Product class in prestashop. To do so, create a new file in override/classes called Product.php and put this code in it :
<?php
class Product extends ProductCore
{
// Here we will put every method or property override
}
In this class, you will copy / paste the static method priceCalculation (it's at line 2567 of original Product.php file for me). When done, just add these lines at the end of the method, just before the self::$_prices[$cache_id] = $price; :
if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
$customer = Context::getContext()->customer;
$nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product` p
JOIN `' . _DB_PREFIX_ . 'order_detail` od
ON p.`id_product` = od.`product_id`
JOIN `' . _DB_PREFIX_ . 'orders` o
ON od.`id_order` = o.`id_order`
WHERE o.`id_customer` = ' . $customer->id . '
AND p.`id_product` = ' . $id_product . '
');
$price += $nbTimesBoughtThisProduct * 10;
}
I did not have the time to test these, but I think that's the way to do what you want to do.
priceCalculation is the method called each time Prestashop needs a product's price. By putting this code at the end of this method, we modify the returned price.
The code first checks if the customer is logged (we can't get orders from him if he is not). If so, a query retrieves the amount of times this customer bought this product in the past. This number is multiplied by ten, and the value is added to the price.
EDIT: If, as Cyril Tourist said, you want to also count the current cart, get this new code (still not tested, but should work) :
if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
$customer = Context::getContext()->customer;
$nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product` p
JOIN `' . _DB_PREFIX_ . 'order_detail` od
ON p.`id_product` = od.`product_id`
JOIN `' . _DB_PREFIX_ . 'orders` o
ON od.`id_order` = o.`id_order`
WHERE o.`id_customer` = ' . $customer->id . '
AND p.`id_product` = ' . $id_product . '
');
$productsInCart = Context::getContext()->cart->getProducts();
foreach ($productsInCart as $productInCart) {
if ($productInCart['id_product'] == 44) {
$nbTimesBoughtThisProduct++;
}
}
$price += $nbTimesBoughtThisProduct * 10;
}
Also, I advice you to store the "44" product ID in a constant, configuration variable, or anything, but not keeping it in the code like that. I did that just for the example.

OpenCart JSON Query Database

I create a custom feed for OpenCart.
I am trying to get a list of order details from OpenCart 1.54, however, I cannot find any JSON. Is there a way to return an error message, if the query fails?
Here is the URL to access:
/index.php?route=feed/api&func=getOrderProducts&orderid=1&email=xyz
My plugin files are here:
http://support.cloudcartconnector.com/hc/en-us/articles/202592798-OpenCart
On my test site, this works fine:
public function getOrderProducts($orderid) {
$query = $this->db->query("SELECT op.*, pr.sku, pr.quantity as stock FROM `" . DB_PREFIX . "order_product` op INNER JOIN `product` pr on op.product_id = pr.product_id WHERE op.order_id = '" . $this->db->escape($orderid) . "'");
return $query->rows;
}
I have no order prefix in my database. Here is the response:
[{"order_product_id":"1","order_id":"1","product_id":"43","name":"MacBook","model":"Product 16","quantity":"1","price":"500.0000","total":"500.0000","tax":"89.5000","reward":"600","sku":"macproduct1","stock":"927"}]
On several live sites, the code fails and I receive a blank white page. Here is the route itself:
// example function - getOrders from the database
private function getOrderProducts() {
if($this->request->get['email'] != "info#mysite.com")
{
return "INVALID EMAIL";
}
$this->load->model('feed/api');
return $this->model_feed_api->getOrderProducts($this->request->get['orderid']);
}
My code for getOrders work fine:
public function getOrders($beginDate, $endDate) {
$query = $this->db->query("select o.*, os.* from `" . DB_PREFIX . "order` o LEFT JOIN " . DB_PREFIX . "order_status os ON (o.order_status_id = os.order_status_id) where o.Date_Added >= $beginDate AND o.Date_Added <= $endDate");
return $query->rows;
}
The route for getOrderProducts actually works. If I put in a bad email, it returns INVALID EMAIL. Is there a way to return an exception message?
$this->request->get['orderid']
Maybe it's order_id (note underscore). It's a common name of the order ID value for OpenCart.
Change that code into
$this->request->get['order_id']

Manually add "Product Model" number to Product Listing in Zen Cart

I am trying to find out how I could manually add the product model to each title in the category product listing in zencart, rather than having the model number appear in its own column.
It appears that any instance of using:
$listing->fields['products_model']
in the "product_listing.php" file will only work when the parameters in the admin are sent to true. This is fine, however I then get two instances of the product model. One with the variable in it's own column (which I don't want), and one wherever else I put the variable.
Here is the section I am referring to, you will notice that a case is set up for the model to have its own column, however I want to place it before the title instead under the product list name case and eliminate the column.
for ($col=0, $n=sizeof($column_list); $col<$n; $col++) {
$lc_align = '';
switch ($column_list[$col]) {
case 'PRODUCT_LIST_MODEL':
$lc_align = '';
$lc_text = $listing->fields['products_model'];
break;
case 'PRODUCT_LIST_NAME':
$lc_align = '';
$lc_text = '<h3 class="itemTitle">' . $listing->fields['products_name'] . '</h3>
Is there a way I can reference the model number and place in the title for each row while bypassing the parameter set in the administration?
Any help would be greatly appreciated.
I would just append the product model number ($listing->fields['products_model']) to the product title:
case 'PRODUCT_LIST_NAME':
$lc_align = '';
$lc_text = '<h3 class="itemTitle">' . $listing->fields['products_name'] . '[' . $listing->fields['products_model'] . ']' . '</h3><div class="listingDescription">' . zen_trunc_string(zen_clean_html(stripslashes(zen_get_products_description($listing->fields['products_id'], $_SESSION['languages_id']))), PRODUCT_LIST_DESCRIPTION) . '</div>';
break;
Remember to then turn off the Model Number column in the Zen Cart Admin.
I haven't tested this in Zen Cart - hope it helps.
After some time, I have figured out the answer to my own question. It was actually much easier than I thought. Hopefully, this will help others who may have wanted to do the same thing.
Go to "includes/index_filters/default_filter.php:
From what I can tell, this is where all the queries are made for the "Product Listing" module to display lists for both a specific category or manufacturer. By default, the current queries do not include "p.products_model". Simply add the column identifier in each query (4 total locations: category, category:all, manufacturer, manufacturer:all).
Example:
// We are asked to show only specific category
$listing_sql = "select " . $select_column_list . " p.products_id, p.products_model, p.products_type, p.master_categories_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, pd.products_description, IF(s.status = 1, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status = 1, s.specials_new_products_price, p.products_price) as final_price, p.products_sort_order, p.product_is_call, p.product_is_always_free_shipping, p.products_qty_box_status
from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " .
TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m, " .
TABLE_PRODUCTS_TO_CATEGORIES . " p2c
where p.products_status = 1
and p.manufacturers_id = m.manufacturers_id
and m.manufacturers_id = '" . (int)$_GET['filter_id'] . "'
and p.products_id = p2c.products_id
and pd.products_id = p2c.products_id
and pd.language_id = '" . (int)$_SESSION['languages_id'] . "'
and p2c.categories_id = '" . (int)$current_category_id . "'" .
$alpha_sort;
}
From there, you will be able to call the product model code "$listing->fields['products_model']" anywhere you would like, without the parameter in the admin back-end interrupting it from showing. In my case, it I included it directly under the product name in the "product_listing.php" file in modules.
Example:
$lc_text = '<h3 class="itemTitle">' . $listing->fields['products_name'] . '</h3><div id=\"listing_model\">Item Code: ' .$listing->fields['products_model'] . '</div>
Hope this helps someone. Why they made you originally have a whole column for the product model is beyond me, as both "Listing New" and "Listing All" both show it in the same column as the title and description.

List By Category View

I have a view all category on the website I am working on (http://www.thetradinghouse.co.nz/view-all). As you can see the products are not in order by category how could I change this as I also would like to do this with the admin product listings too.
V: 1.5.1.3
This kind of thing requires quite a bit of editing in the respective model/catalog/product.php files. This is how for the catalog side of things. The admin should require something similar. To start with, you're going to need to attach the category to the SQL like it does when the category filter is used
if (!empty($data['filter_category_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
}
Would then become just
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
Since you want it to be available regardless of the filter_category_id
Then you need to add the category id as a sort option
$sort_data = array(
'pd.name',
'p.model',
'p.quantity',
'p.price',
'rating',
'p.sort_order',
'p.date_added'
);
will need p2c.category_id adding to it
$sort_data = array(
'pd.name',
'p2c.category_id',
'p.model',
'p.quantity',
'p.price',
'rating',
'p.sort_order',
'p.date_added'
);
And also set the default sort if none is supplied, changing
$sql .= " ORDER BY p.sort_order";
To
$sql .= " ORDER BY p2c.category_id";
Finally you'll need to edit the controller for the said pages and find the default of the sort value, and change it to p2c.category_id

Categories