Jump to content
Sign in to follow this  
kiggo

Мини описание товара в категории (ошибка null) нужна помощь

Recommended Posts

День добрый. 

 

Сразу прошу ногами не пинать - я только учусь :)

 

Есть необходимость добавить мини описание товара в категории.

 

в category.php

 

$this->data['products'][] = array(
'product_id'  => $result['product_id'],
'thumb'       => $image,
'thumbwidth'  => $imagewidth,
'thumbheight' => $imageheight,
'name'        => $result['name'],
'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 300) . '..',
'description_mini' => html_entity_decode ($result['description_mini']),
'price'       => $price,
'special'     => $special,
'tax'         => $tax,
'rating'      => $result['rating'],
'reviews'     => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
'href'        => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url)
);
}
 
 
в category.tpl добавил по аналогии
html += '<div class="name">' + $(element).find('.name').html() + '</div>';
   html += '<div class="desc_mini">' + $(element).find('.description_mini').html() + '</div>';
var price = $(element).find('.price').html();
 
if (price != null) {
html += '<div class="price">' + price  + '</div>';
}
html += '<div class="description">' + $(element).find('.description').html() + '</div>';
 
 
в результате хотелось бы получить вывод мини описания а получаю null
 
Очень буду благодарен за помощь.
 

post-670964-0-20438700-1417609324_thumb.png

Share this post


Link to post
Share on other sites
в category.tpl добавил по аналогии
html += '<div class="name">' + $(element).find('.name').html() + '</div>';
   html += '<div class="desc_mini">' + $(element).find('.description_mini').html() + '</div>';
var price = $(element).find('.price').html();

 

 

 

и для сетки и для списка?

Share this post


Link to post
Share on other sites

Все же кто может помочь ?

Share this post


Link to post
Share on other sites

Если вы не редактировали модель, то:

Ошибка для начала здесь:

'description_mini' => html_entity_decode ($result['description_mini']),

 

Должно быть, к примеру:

'description_mini' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 100) . '..',

 

И для тплки вы добавили див в нужное место ? <div class="description_mini"><?php echo $product['description_mini]; ?></div>

 

Я так понимаю будет еще вид отображения товаров списком с "полным" описанием?

Может тогда, чтобы не дублировать контент, пойти путем открывания в CSS отображения описания товара в виде сетка и ограничить просто видимую высоту блока описания?

Share this post


Link to post
Share on other sites

1. Отредактировал модель:

'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 300),

'description_mini' => utf8_substr(strip_tags(html_entity_decode($result['description_mini'], ENT_QUOTES, 'UTF-8')), 0, 15),
 
Ошибка не изменилась.
 
DIV стоит на своем месте.
 
Полое описание будет отображаться в виде сетка, вместе с мини описанием - контент не дублируется.
В моем случае выводиться описание до 15 знаков 

Share this post


Link to post
Share on other sites

Если интересно, я мини описание добавил отдельной переменной. Естественно, добавил в таблицу описаний новое поле (short_descr) и сделал его вывод именно в списке товаров категории. Правда у меня этот вывод для списка, а не для сетки. Условие - если короткое описание заполнено - выводится короткое описание, если не заполнено - выводится полное описание.

Необходимо редактировать несколько файлов:

 

Для вывода - сам шаблон вывода, контроллер в папке catalog

\catalog\view\theme\default\template\product\category.tpl

\catalog\controller\product\category.php

Для сохранения через карточку товара - сам шаблон карточки товара и контроллер этой карточки в папке admin

\admin\view\template\catalog\product_form.tpl

\admin\controller\catalog\product.php

Ну и, естественно, языковый файл в папке admin

\admin\language\russian\catalog\product.php

Share this post


Link to post
Share on other sites

В шаблоне изначально введена переменная description_mini которая хранит мини описание товара. В карточке она есть. В SQL - храниться.

Вывести не могу :(

post-670964-0-39446000-1417773872_thumb.jpg

post-670964-0-29275700-1417773873_thumb.jpg

Share this post


Link to post
Share on other sites

Для вывода я вам написал, какие файлы править.

Находите там место, куда надо выводить и вставляете код вывода.

Вот мой код из файла category.tpl:

<div class="description">
 <?php if (!isset($product['short_descr'])) { ?>
  <?php echo $product['description']; ?>
 <?php } else { ?>
  <?php echo $product['short_descr']; ?>
 <?php } ?>
</div>

У вас будет вместо short_descr description_mini

Ну и условие вывода надо прописывать для сетки, а не для списка

 

Тоже самое, кстати, для поиска не мешает сделать.

Share this post


Link to post
Share on other sites

kiggo

 

Тогда выложите здесь под спойлером содержимое трех файлов:

catalog/model/catalog/product.php

catalog/controller/product/category.php

catalog/view/theme/*******/template/product/category.tpl

Share this post


Link to post
Share on other sites

catalog/model/catalog/product.php

<?php

class ModelCatalogProduct extends Model {
 
private $FOUND_ROWS;
 
public function getFoundProducts() {
return $this->FOUND_ROWS;
}
 
public function updateViewed($product_id) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET viewed = (viewed + 1) WHERE product_id = '" . (int)$product_id . "'");
}
 
public function getProduct($product_id) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$query = $this->db->query("SELECT DISTINCT *, pd.name AS name, p.image, m.name AS manufacturer, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$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)$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, (SELECT points FROM " . DB_PREFIX . "product_reward pr WHERE pr.product_id = p.product_id AND customer_group_id = '" . (int)$customer_group_id . "') AS reward, (SELECT ss.name FROM " . DB_PREFIX . "stock_status ss WHERE ss.stock_status_id = p.stock_status_id AND ss.language_id = '" . (int)$this->config->get('config_language_id') . "') AS stock_status, (SELECT wcd.unit FROM " . DB_PREFIX . "weight_class_description wcd WHERE p.weight_class_id = wcd.weight_class_id AND wcd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS weight_class, (SELECT lcd.unit FROM " . DB_PREFIX . "length_class_description lcd WHERE p.length_class_id = lcd.length_class_id AND lcd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS length_class, (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 COUNT(*) AS total FROM " . DB_PREFIX . "review r2 WHERE r2.product_id = p.product_id AND r2.status = '1' GROUP BY r2.product_id) AS reviews, p.sort_order 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) LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) WHERE p.product_id = '" . (int)$product_id . "' AND 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 ($query->num_rows) {
return array(
'product_id'       => $query->row['product_id'],
'seo_title'        => $query->row['seo_title'],
'seo_h1'           => $query->row['seo_h1'],
'name'             => $query->row['name'],
'description'      => $query->row['description'],
'description_mini' => $query->row['description_mini'],
'meta_description' => $query->row['meta_description'],
'meta_keyword'     => $query->row['meta_keyword'],
'tag'              => $query->row['tag'],
'model'            => $query->row['model'],
'sku'              => $query->row['sku'],
'upc'              => $query->row['upc'],
'ean'              => $query->row['ean'],
'jan'              => $query->row['jan'],
'isbn'             => $query->row['isbn'],
'mpn'              => $query->row['mpn'],
'location'         => $query->row['location'],
'quantity'         => $query->row['quantity'],
'stock_status'     => $query->row['stock_status'],
'image'            => $query->row['image'],
'manufacturer_id'  => $query->row['manufacturer_id'],
'manufacturer'     => $query->row['manufacturer'],
'price'            => ($query->row['discount'] ? $query->row['discount'] : $query->row['price']),
'special'          => $query->row['special'],
'reward'           => $query->row['reward'],
'points'           => $query->row['points'],
'tax_class_id'     => $query->row['tax_class_id'],
'date_available'   => $query->row['date_available'],
'weight'           => $query->row['weight'],
'weight_class_id'  => $query->row['weight_class_id'],
'length'           => $query->row['length'],
'width'            => $query->row['width'],
'height'           => $query->row['height'],
'length_class_id'  => $query->row['length_class_id'],
'subtract'         => $query->row['subtract'],
'rating'           => round($query->row['rating']),
'reviews'          => $query->row['reviews'] ? $query->row['reviews'] : 0,
'minimum'          => $query->row['minimum'],
'sort_order'       => $query->row['sort_order'],
'status'           => $query->row['status'],
'date_added'       => $query->row['date_added'],
'date_modified'    => $query->row['date_modified'],
'viewed'           => $query->row['viewed']
);
} else {
return false;
}
}
 
public function getProducts($data = array()) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
if (!empty($data['coolfilter'])) {
$coolfilter = $data['coolfilter'];
} else {
$coolfilter = 0;
}
 
// Start coolfilter
$currency_value = $this->currency->getValue();
$tax_rate = $this->tax->getTax(100, 9);
 
$sql_add_table_prices = '';
$sql_where_prices = '';
$sql_where_manufacteurs = '';
$sql_add_table_options = '';
$sql_where_options = '';
$sql_add_table_attributes = '';
$sql_where_attributes = '';
//standart filter
$sql_add_table_parameters = '';
$sql_where_parameters = '';
//standart filter
if ($coolfilter) {
 
 
 
 foreach (explode(';', $coolfilter) as $option) {
$values = explode(':', $option);
 
 
if ($values[0] == 'm' && preg_match('/^[\d\,]*$/', $values[1])) {
$sql_where_manufacteurs = ' AND p.manufacturer_id IN (' . $this->db->escape($values[1]) . ')';
}
if (preg_match('/o_\d+/', $values[0]) && preg_match('/^[\d\,]*$/', $values[1])) {
$option_id = $this->db->escape($values[0]);
$sql_add_table_options .= ' LEFT JOIN ' . DB_PREFIX . 'product_option_value pov' . $option_id . ' ON (p.product_id = pov' . $option_id . '.product_id)';
 
$sql_where_options .= ' AND pov' . $option_id . '.option_value_id IN (' . $this->db->escape($values[1]) .') AND (pov' . $option_id . '.subtract=0 OR pov' . $option_id . '.subtract=1 AND pov' . $option_id . '.quantity > 0)';
}
 
 
if (preg_match('/a_\d+/', $values[0])) {
 
 
 
$attribute_id = $this->db->escape($values[0]);
$sql_add_table_attributes .= " LEFT JOIN " . DB_PREFIX . "product_attribute atr" . $attribute_id . " ON (p.product_id = atr" . $attribute_id . ".product_id)";
$get_id = explode("_", $values[0]);
 
$values[1] = explode(",", $values[1]);
for ($i = 0; $i < count($values[1]); $i++) {
$values[1][$i] = $this->db->escape($values[1][$i]);
}
 
$values[1] = "'" . implode("','", $values[1]) . "'";
 
$sql_where_attributes .= " AND (atr" . $attribute_id . ".language_id = '" . (int)$this->config->get('config_language_id') . "' AND atr" . $attribute_id . ".attribute_id = '" . (int)$get_id[1] . "' AND atr" . $attribute_id . ".text IN (" . $values[1] . "))";
}
 
if ($values[0] == 'p') {
 
$values[1] = explode(",", $values[1]);
if (!isset($values[1][0])) {
$values[1][0] = 0;
} else {
$values[1][0] /= $currency_value;
}
 
if (!isset($values[1][1])) {
$values[1][1] = 9999999999;
} else {
$values[1][1] /= $currency_value;
}
 
for ($i = 0; $i < 2; $i++) {
$values[1][$i] = $this->db->escape($values[1][$i]);
}
 
if (!empty($data['coolfilter_category_id'])) {
$category_id = ' AND ct.category_id IN (' . $data['coolfilter_category_id'] . ')';
} else {
$category_id = '';
}
 
$sql_add_table_prices .= " LEFT JOIN (SELECT pr.product_id, pr.price, (SELECT pd2.price FROM `" . DB_PREFIX . "product_discount` pd2 WHERE pd2.product_id = pr.product_id AND pd2.customer_group_id = '" . $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) discount, (SELECT ps.price FROM `" . DB_PREFIX . "product_special` ps WHERE ps.product_id = pr.product_id AND ps.customer_group_id = '" . $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) special FROM `" . DB_PREFIX . "product` pr LEFT JOIN `" . DB_PREFIX . "product_to_category` ct ON (pr.product_id = ct.product_id) WHERE pr.status = '1'" . $category_id . ") tb ON (p.product_id = tb.product_id)";
$sql_where_prices .= "AND tb.price >= '" . $values[1][0] . "' AND (tb.discount IS NULL OR tb.discount >= '" . $values[1][0] . "') AND (tb.special IS NULL OR tb.special >= '" . $values[1][0] . "') AND tb.price <= '" . $values[1][1] . "' AND (tb.discount IS NULL OR tb.discount <= '" . $values[1][1] . "') AND (tb.special IS NULL OR tb.special <= '" . $values[1][1] . "')";
}
//standart filter
if (preg_match('/p_\d+/', $values[0]) && preg_match('/^[\d\,]*$/', $values[1])) {
 
$parameter_id = $this->db->escape($values[0]);
 
 
$sql_add_table_parameters .= " LEFT JOIN " . DB_PREFIX . "product_filter par" . $parameter_id . " ON (p.product_id = par" . $parameter_id . ".product_id) LEFT JOIN  " . DB_PREFIX . "filter_description fd" . $parameter_id . "  ON (par" . $parameter_id . ".filter_id = fd" . $parameter_id . ".filter_id) ";
$get_id = explode("_", $values[0]);
 
$values[1] = explode(",", $values[1]);
for ($i = 0; $i < count($values[1]); $i++) {
$values[1][$i] = $this->db->escape($values[1][$i]);
 
 
}
 
$values[1] = "'" . implode("','", $values[1]) . "'";
 
$sql_where_parameters .= " AND (fd" . $parameter_id . ".language_id = '" . (int)$this->config->get('config_language_id') . "' AND par" . $parameter_id . ".filter_id IN (" . $values[1] . "))";
 
 
}
//standart filter
}
 }
 
 
// End coolfilter
 
$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)$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)$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'])) {
$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";
}
 
// start coolfilter
$sql .= $sql_add_table_options;
$sql .= $sql_add_table_attributes;
$sql .= $sql_add_table_prices;
$sql .= $sql_add_table_parameters;
// End coolfilter
 
$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\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'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.sku) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.upc) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.ean) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.jan) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.isbn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($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 .= $sql_where_manufacteurs;
$sql .= $sql_where_attributes;
$sql .= $sql_where_options;
$sql .= $sql_where_prices; //print_r($sql);
//standart filter
$sql .= $sql_where_parameters; //print_r($sql);
//standart filter
 
$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;
}
 
public function getProductSpecials($data = array()) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$sql = "SELECT DISTINCT ps.product_id, (SELECT AVG(rating) FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = ps.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating FROM " . DB_PREFIX . "product_special ps LEFT JOIN " . DB_PREFIX . "product p ON (ps.product_id = p.product_id) 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.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND ps.customer_group_id = '" . (int)$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())) GROUP BY ps.product_id";
 
$sort_data = array(
'pd.name',
'p.model',
'ps.price',
'rating',
'p.sort_order'
);
 
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'] . ")";
} 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;
}
 
public function getLatestProducts($limit) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$product_data = $this->cache->get('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id') . '.' . $customer_group_id . '.' . (int)$limit);
 
if (!$product_data) { 
$query = $this->db->query("SELECT p.product_id FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' ORDER BY p.date_added DESC LIMIT " . (int)$limit);
 
foreach ($query->rows as $result) {
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
 
$this->cache->set('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' . $customer_group_id . '.' . (int)$limit, $product_data);
}
 
return $product_data;
}
 
public function getPopularProducts($limit) {
$product_data = array();
 
$query = $this->db->query("SELECT p.product_id FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' ORDER BY p.viewed, p.date_added DESC LIMIT " . (int)$limit);
 
foreach ($query->rows as $result) {
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
 
return $product_data;
}
 
public function getBestSellerProducts($limit) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$product_data = $this->cache->get('product.bestseller.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' . $customer_group_id . '.' . (int)$limit);
 
if (!$product_data) { 
$product_data = array();
 
$query = $this->db->query("SELECT op.product_id, COUNT(*) AS total FROM " . DB_PREFIX . "order_product op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id) LEFT JOIN `" . DB_PREFIX . "product` p ON (op.product_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE o.order_status_id > '0' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' GROUP BY op.product_id ORDER BY total DESC LIMIT " . (int)$limit);
 
foreach ($query->rows as $result) {
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
 
$this->cache->set('product.bestseller.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' . $customer_group_id . '.' . (int)$limit, $product_data);
}
 
return $product_data;
}
 
public function getProductAttributes($product_id) {
$product_attribute_group_data = array();
 
$product_attribute_group_query = $this->db->query("SELECT ag.attribute_group_id, agd.name FROM " . DB_PREFIX . "product_attribute pa LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id) LEFT JOIN " . DB_PREFIX . "attribute_group ag ON (a.attribute_group_id = ag.attribute_group_id) LEFT JOIN " . DB_PREFIX . "attribute_group_description agd ON (ag.attribute_group_id = agd.attribute_group_id) WHERE pa.product_id = '" . (int)$product_id . "' AND agd.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY ag.attribute_group_id ORDER BY ag.sort_order, agd.name");
 
foreach ($product_attribute_group_query->rows as $product_attribute_group) {
$product_attribute_data = array();
 
$product_attribute_query = $this->db->query("SELECT a.attribute_id, ad.name, pa.text FROM " . DB_PREFIX . "product_attribute pa LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id) LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id) WHERE pa.product_id = '" . (int)$product_id . "' AND a.attribute_group_id = '" . (int)$product_attribute_group['attribute_group_id'] . "' AND ad.language_id = '" . (int)$this->config->get('config_language_id') . "' AND pa.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY a.sort_order, ad.name");
 
foreach ($product_attribute_query->rows as $product_attribute) {
$product_attribute_data[] = array(
'attribute_id' => $product_attribute['attribute_id'],
'name'         => $product_attribute['name'],
'text'         => $product_attribute['text']
);
}
 
$product_attribute_group_data[] = array(
'attribute_group_id' => $product_attribute_group['attribute_group_id'],
'name'               => $product_attribute_group['name'],
'attribute'          => $product_attribute_data
);
}
 
return $product_attribute_group_data;
}
 
public function getProductOptions($product_id) {
$product_option_data = array();
 
$product_option_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE po.product_id = '" . (int)$product_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY o.sort_order");
 
foreach ($product_option_query->rows as $product_option) {
if ($product_option['type'] == 'select' || $product_option['type'] == 'radio' || $product_option['type'] == 'checkbox' || $product_option['type'] == 'image') {
$product_option_value_data = array();
 
$product_option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_id = '" . (int)$product_id . "' AND pov.product_option_id = '" . (int)$product_option['product_option_id'] . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY ov.sort_order");
 
foreach ($product_option_value_query->rows as $product_option_value) {
$product_option_value_data[] = array(
'product_option_value_id' => $product_option_value['product_option_value_id'],
'option_value_id'         => $product_option_value['option_value_id'],
'name'                    => $product_option_value['name'],
'image'                   => $product_option_value['image'],
'quantity'                => $product_option_value['quantity'],
'subtract'                => $product_option_value['subtract'],
'price'                   => $product_option_value['price'],
'price_prefix'            => $product_option_value['price_prefix'],
'weight'                  => $product_option_value['weight'],
'weight_prefix'           => $product_option_value['weight_prefix']
);
}
 
$product_option_data[] = array(
'product_option_id' => $product_option['product_option_id'],
'option_id'         => $product_option['option_id'],
'name'              => $product_option['name'],
'type'              => $product_option['type'],
'option_value'      => $product_option_value_data,
'required'          => $product_option['required']
);
} else {
$product_option_data[] = array(
'product_option_id' => $product_option['product_option_id'],
'option_id'         => $product_option['option_id'],
'name'              => $product_option['name'],
'type'              => $product_option['type'],
'option_value'      => $product_option['option_value'],
'required'          => $product_option['required']
);
}
}
 
return $product_option_data;
}
 
public function getProductDiscounts($product_id) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "' AND customer_group_id = '" . (int)$customer_group_id . "' AND quantity > 1 AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY quantity ASC, priority ASC, price ASC");
 
return $query->rows;
}
 
public function getProductImages($product_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "' ORDER BY sort_order ASC");
 
return $query->rows;
}
 
public function getProductRelated($product_id) {
$product_data = array();
 
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.related_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.product_id = '" . (int)$product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
 
foreach ($query->rows as $result) { 
$product_data[$result['related_id']] = $this->getProduct($result['related_id']);
}
 
return $product_data;
}
 
public function getProductRelated2($product_id) {
$product_data = array();
 
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related2 pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.related_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.product_id = '" . (int)$product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
 
foreach ($query->rows as $result) { 
$product_data[$result['related_id']] = $this->getProduct($result['related_id']);
}
 
return $product_data;
}
 
public function getArticleRelated($product_id) {
$article_data = array();
$this->load->model('blog/article');
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "blog_related_product np LEFT JOIN " . DB_PREFIX . "article p ON (np.article_id = p.article_id) LEFT JOIN " . DB_PREFIX . "article_to_store p2s ON (p.article_id = p2s.article_id) WHERE np.product_id = '" . (int)$product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
 
foreach ($query->rows as $result) { 
$article_data[$result['article_id']] = $this->model_blog_article->getArticle($result['article_id']);
}
 
return $article_data;
}
 
public function getProductLayoutId($product_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int)$product_id . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'");
 
if ($query->num_rows) {
return $query->row['layout_id'];
} else {
return false;
}
}
 
public function getCategories($product_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
 
return $query->rows;
}
 
public function getTotalProducts($data = array()) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
// Start coolfilter
if (!empty($data['coolfilter'])) {
$coolfilter = $data['coolfilter'];
} else {
$coolfilter = 0;
}
 
 
$currency_value = $this->currency->getValue();
 
$sql_add_table_prices = '';
$sql_where_prices = '';
$sql_where_manufacteurs = '';
$sql_add_table_options = '';
$sql_where_options = '';
$sql_add_table_attributes = '';
$sql_where_attributes = '';
//standart filter
$sql_add_table_parameters  = '';
$sql_where_parameters  = '';
//standart filter
 
if ($coolfilter) {
 
 foreach (explode(';', $coolfilter) as $option) {
$values = explode(':', $option);
 
 
if ($values[0] == 'm' && preg_match('/^[\d\,]*$/', $values[1])) {
$sql_where_manufacteurs = ' AND p.manufacturer_id IN (' . $this->db->escape($values[1]) . ')';
}
if (preg_match('/o_\d+/', $values[0]) && preg_match('/^[\d\,]*$/', $values[1])) {
$option_id = $this->db->escape($values[0]);
$sql_add_table_options .= ' LEFT JOIN ' . DB_PREFIX . 'product_option_value pov' . $option_id . ' ON (p.product_id = pov' . $option_id . '.product_id)';
$values[1] = preg_replace("/[^0-9\,]/", "", $values[1]);
$sql_where_options .= ' AND pov' . $option_id . '.option_value_id IN (' . $this->db->escape($values[1]) .') AND (pov' . $option_id . '.subtract=0 OR pov' . $option_id . '.subtract=1 AND pov' . $option_id . '.quantity > 0)';
}
if (preg_match('/a_\d+/', $values[0])) {
$attribute_id = $this->db->escape($values[0]);
$sql_add_table_attributes .= ' LEFT JOIN ' . DB_PREFIX . 'product_attribute atr' . $attribute_id . ' ON (p.product_id = atr' . $attribute_id . '.product_id)';
$get_id = explode("_", $values[0]);
 
$values[1] = explode(",", $values[1]);
for ($i = 0; $i < count($values[1]); $i++) {
$values[1][$i] = $this->db->escape($values[1][$i]);
}
 
$values[1] = "'" . implode("','", $values[1]) . "'";
 
$sql_where_attributes .= " AND (atr" . $attribute_id . ".language_id = '" . (int)$this->config->get('config_language_id') . "' AND atr" . $attribute_id . ".attribute_id = '" . (int)$get_id[1] . "' AND atr" . $attribute_id . ".text IN (" . $values[1] . "))";
}
if ($values[0] == 'p') {
 
if (isset($values[1])) {
   $values[1] = explode(",", $values[1]);
}
 
if (!isset($values[1][0])) {
$values[1][0] = 0;
} else {
$values[1][0] = $values[1][0]/$currency_value;
 
}
 
if (!isset($values[1][1])) {
$values[1][1] = 9999999;
} else {
$values[1][1] = $values[1][1]/$currency_value;
}
 
for ($i = 0; $i < 2; $i++) {
$values[1][$i] = (float)$values[1][$i];
}
 
if (!empty($data['coolfilter_category_id'])) {
$category_id = ' AND ct.category_id IN (' . $data['coolfilter_category_id'] . ')';
} else {
$category_id = '';
}
 
$sql_add_table_prices .= " LEFT JOIN (SELECT pr.product_id, pr.price, (SELECT pd2.price FROM `" . DB_PREFIX . "product_discount` pd2 WHERE pd2.product_id = pr.product_id AND pd2.customer_group_id = '" . $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) discount, (SELECT ps.price FROM `" . DB_PREFIX . "product_special` ps WHERE ps.product_id = pr.product_id AND ps.customer_group_id = '" . $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) special FROM `" . DB_PREFIX . "product` pr LEFT JOIN `" . DB_PREFIX . "product_to_category` ct ON (pr.product_id = ct.product_id) WHERE pr.status = '1'" . $category_id . ") tb ON (p.product_id = tb.product_id)";
$sql_where_prices .= "AND tb.price >= '" . $values[1][0] . "' AND (tb.discount IS NULL OR tb.discount >= '" . $values[1][0] . "') AND (tb.special IS NULL OR tb.special >= '" . $values[1][0] . "') AND tb.price <= '" . $values[1][1] . "' AND (tb.discount IS NULL OR tb.discount <= '" . $values[1][1] . "') AND (tb.special IS NULL OR tb.special <= '" . $values[1][1] . "')";
}
 
 
//standart filter
 
if (preg_match('/p_\d+/', $values[0]) && preg_match('/^[\d\,]*$/', $values[1])) {
$parameter_id = $this->db->escape($values[0]);
 
$sql_add_table_parameters .= " LEFT JOIN " . DB_PREFIX . "product_filter par" . $parameter_id . " ON (p.product_id = par" . $parameter_id . ".product_id) LEFT JOIN  " . DB_PREFIX . "filter_description fd" . $parameter_id . "  ON (par" . $parameter_id . ".filter_id = fd" . $parameter_id . ".filter_id) ";
$get_id = explode("_", $values[0]);
 
$values[1] = explode(",", $values[1]);
for ($i = 0; $i < count($values[1]); $i++) {
$values[1][$i] = $this->db->escape($values[1][$i]);
 
 
}
 
$values[1] = "'" . implode("','", $values[1]) . "'";
 
$sql_where_parameters .= " AND (fd" . $parameter_id . ".language_id = '" . (int)$this->config->get('config_language_id') . "' AND par" . $parameter_id . ".filter_id IN (" . $values[1] . "))";// 
}
}
 
// End coolfilter
 
$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";
}
 
// start coolfilter
$sql .= $sql_add_table_options;
$sql .= $sql_add_table_attributes;
$sql .= $sql_add_table_prices;
// End coolfilter
//standart filter
$sql .= $sql_add_table_parameters;
//standart filter
 
$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\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'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.sku) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.upc) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.ean) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.jan) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($data['filter_name'])) {
$sql .= " OR LCASE(p.isbn) = '" . $this->db->escape(utf8_strtolower($data['filter_name'])) . "'";
}
 
if (!empty($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 .= $sql_where_manufacteurs;
$sql .= $sql_where_attributes;
$sql .= $sql_where_options;
$sql .= $sql_where_prices; //print_r($sql.'<br><br>');
//standart filter
$sql .= $sql_where_parameters;
//standart filter
 
 
$query = $this->db->query($sql);
 
return $query->row['total'];
}
 
public function getProfiles($product_id) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
return $this->db->query("SELECT `pd`.* FROM `" . DB_PREFIX . "product_profile` `pp` JOIN `" . DB_PREFIX . "profile_description` `pd` ON `pd`.`language_id` = " . (int)$this->config->get('config_language_id') . " AND `pd`.`profile_id` = `pp`.`profile_id` JOIN `" . DB_PREFIX . "profile` `p` ON `p`.`profile_id` = `pd`.`profile_id` WHERE `product_id` = " . (int)$product_id . " AND `status` = 1 AND `customer_group_id` = " . (int)$customer_group_id . " ORDER BY `sort_order` ASC")->rows;
 
}
 
public function getProfile($product_id, $profile_id) {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
return $this->db->query("SELECT * FROM `" . DB_PREFIX . "profile` `p` JOIN `" . DB_PREFIX . "product_profile` `pp` ON `pp`.`profile_id` = `p`.`profile_id` AND `pp`.`product_id` = " . (int)$product_id . " WHERE `pp`.`profile_id` = " . (int)$profile_id . " AND `status` = 1 AND `pp`.`customer_group_id` = " . (int)$customer_group_id)->row;
}
 
public function getProductRelated_by_category($category_id, $limit) {
 
$product_data = array();
 
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related_wb pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.product_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.category_id = '" . (int)$category_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' LIMIT " . (int)$limit); 
 
foreach ($query->rows as $result) { 
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
return $product_data;
}
 
public function getProductRelated_by_manufacturer($manufacturer_id, $limit) {
 
$product_data = array();
 
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related_mn pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.product_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.manufacturer_id = '" . (int)$manufacturer_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' LIMIT " . (int)$limit); 
 
foreach ($query->rows as $result) { 
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
return $product_data;
}
 
public function getTotalProductSpecials() {
if ($this->customer->isLogged()) {
$customer_group_id = $this->customer->getCustomerGroupId();
} else {
$customer_group_id = $this->config->get('config_customer_group_id');
}
 
$query = $this->db->query("SELECT COUNT(DISTINCT ps.product_id) AS total FROM " . DB_PREFIX . "product_special ps LEFT JOIN " . DB_PREFIX . "product p ON (ps.product_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND ps.customer_group_id = '" . (int)$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()))");
 
if (isset($query->row['total'])) {
return $query->row['total'];
} else {
return 0;
}
}
}

?>

 

 

catalog/controller/product/category.php

<?php 
class ControllerProductCategory extends Controller {  
public function index() { 
$this->language->load('product/category');
 
$this->load->model('catalog/category');
 
$this->load->model('catalog/product');
 
$this->load->model('tool/image'); 
 
if (isset($this->request->get['filter'])) {
$filter = $this->request->get['filter'];
$this->document->setRobots('noindex,follow');
} else {
$filter = '';
}
 
if (isset($this->request->get['sort'])) {
$sort = $this->request->get['sort'];
$this->document->setRobots('noindex,follow');
} else {
$sort = 'p.sort_order';
}
 
if (isset($this->request->get['order'])) {
$order = $this->request->get['order'];
} else {
$order = 'ASC';
}
 
if (isset($this->request->get['coolfilter'])) {
       $coolfilter = $this->request->get['coolfilter'];
$this->document->setRobots('noindex,follow');
} else {
       $coolfilter = '';
}
 
if (isset($this->request->get['page'])) {
$page = $this->request->get['page'];
$this->document->setRobots('noindex,follow');
} else { 
$page = 1;
}
 
if (isset($this->request->get['limit'])) {
$limit = $this->request->get['limit'];
$this->document->setRobots('noindex,follow');
} else {
$limit = $this->config->get('config_catalog_limit');
}
 
$this->data['breadcrumbs'] = array();
 
$this->data['breadcrumbs'][] = array(
'text'      => $this->language->get('text_home'),
'href'      => $this->url->link('common/home'),
'separator' => false
);
 
if (isset($this->request->get['path'])) {
$url = '';
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['coolfilter'])) {
         $url .= '&coolfilter=' . $this->request->get['coolfilter'];
       }
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
$path = '';
 
$parts = explode('_', (string)$this->request->get['path']);
 
$category_id = (int)array_pop($parts);
 
foreach ($parts as $path_id) {
if (!$path) {
$path = (int)$path_id;
} else {
$path .= '_' . (int)$path_id;
}
 
$category_info = $this->model_catalog_category->getCategory($path_id);
 
if ($category_info || $path_id == 0) {
 
if ($path_id == 0) {
$category_info['name'] = $this->language->get('text_all_products');
}
$this->data['breadcrumbs'][] = array(
'text'      => $category_info['name'],
'href'      => $this->url->link('product/category', 'path=' . $path . $url),
'separator' => $this->language->get('text_separator')
);
}
}
} else {
$category_id = 0;
}
 
$category_info = $this->model_catalog_category->getCategory($category_id);
 
if ($category_info || $category_id == 0) {
if ($category_id == 0) {
$category_info = array('name' => $this->language->get('text_all_products'),
'seo_title' => '',
'meta_description' => '',
'meta_keyword' => '',
'seo_h1' => $this->language->get('text_all_products'),
'image' => '',
'description' => '');
//india style fix
$this->request->get['path'] = 0;
//india style fix
}
 
if ($category_info['seo_title']) {
  $this->document->setTitle($category_info['seo_title']);
} else {
  $this->document->setTitle($category_info['name']);
}
 
$this->document->setDescription($category_info['meta_description']);
$this->document->setKeywords($category_info['meta_keyword']);
 
if ($category_info['seo_h1']) {
$this->data['heading_title'] = $category_info['seo_h1'];
} else {
$this->data['heading_title'] = $category_info['name'];
}
 
$this->document->addScript('catalog/view/javascript/jquery/jquery.total-storage.min.js');
$this->document->addScript('catalog/view/javascript/jquery/jail/jail.min.js');
 
$this->data['text_refine'] = $this->language->get('text_refine');
$this->data['text_empty'] = $this->language->get('text_empty');
$this->data['text_quantity'] = $this->language->get('text_quantity');
$this->data['text_manufacturer'] = $this->language->get('text_manufacturer');
$this->data['text_model'] = $this->language->get('text_model');
$this->data['text_price'] = $this->language->get('text_price');
$this->data['text_tax'] = $this->language->get('text_tax');
$this->data['text_points'] = $this->language->get('text_points');
$this->data['text_compare'] = sprintf($this->language->get('text_compare'), (isset($this->session->data['compare']) ? count($this->session->data['compare']) : 0));
$this->data['text_display'] = $this->language->get('text_display');
$this->data['text_list'] = $this->language->get('text_list');
$this->data['text_grid'] = $this->language->get('text_grid');
$this->data['text_sort'] = $this->language->get('text_sort');
$this->data['text_limit'] = $this->language->get('text_limit');
 
$this->data['button_cart'] = $this->language->get('button_cart');
$this->data['button_wishlist'] = $this->language->get('button_wishlist');
$this->data['button_compare'] = $this->language->get('button_compare');
$this->data['button_continue'] = $this->language->get('button_continue');
 
// Set the last category breadcrumb
$url = '';
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['coolfilter'])) {
         $url .= '&coolfilter=' . $this->request->get['coolfilter'];
       }
 
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
 
if (isset($this->request->get['coolfilter'])) {
         $url .= '&coolfilter=' . $this->request->get['coolfilter'];
       }
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
$this->data['breadcrumbs'][] = array(
'text'      => $category_info['name'],
'href'      => $this->url->link('product/category', 'path=' . $this->request->get['path']),
'separator' => $this->language->get('text_separator')
);
 
if ($category_info['image']) {
$this->data['thumb'] = $this->model_tool_image->resize($category_info['image'], $this->config->get('config_image_category_width'), $this->config->get('config_image_category_height'));
$this->document->setOgImage($this->data['thumb']);
} else {
$this->data['thumb'] = '';
}
 
$this->data['description'] = html_entity_decode($category_info['description'], ENT_QUOTES, 'UTF-8');
$this->data['compare'] = $this->url->link('product/compare');
 
$url = '';
 
if (isset($this->request->get['filter'])) {
$url .= '&filter=' . $this->request->get['filter'];
}
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['coolfilter'])) {
         $url .= '&coolfilter=' . $this->request->get['coolfilter'];
       }
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
$this->data['categories'] = array();
 
$results = $this->model_catalog_category->getCategories($category_id);
 
foreach ($results as $result) {
$data = array(
'filter_category_id'  => $result['category_id'],
'filter_sub_category' => true,
'coolfilter'         => $coolfilter
);
 
$product_total = $this->model_catalog_product->getTotalProducts($data);
 
$this->data['categories'][] = array(
'name'  => $result['name'] . ($this->config->get('config_product_count') ? ' (' . $product_total . ')' : ''),
'count' => $product_total,
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '_' . $result['category_id'] . $url)
);
}
 
$this->data['products'] = array();
 
$data = array(
'filter_category_id' => $category_id,
'filter_filter'      => $filter, 
'sort'               => $sort,
'order'              => $order,
'start'              => ($page - 1) * $limit,
'limit'              => $limit,
'coolfilter'         => $coolfilter
);
 
$product_total = $this->model_catalog_product->getTotalProducts($data); 
 
$results = $this->model_catalog_product->getProducts($data);
 
foreach ($results as $result) {
if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $this->config->get('config_image_product_width'), $this->config->get('config_image_product_height'));
$imagewidth = $this->config->get('config_image_product_width');
$imageheight = $this->config->get('config_image_product_height');
} else {
$image = false;
$imagewidth = '';
$imageheight = '';
}
 
if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
$price = $this->currency->format($this->tax->calculate($result['price'], $result['tax_class_id'], $this->config->get('config_tax')));
} else {
$price = false;
}
 
if ((float)$result['special']) {
$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')));
} else {
$special = false;
}
 
if ($this->config->get('config_tax')) {
$tax = $this->currency->format((float)$result['special'] ? $result['special'] : $result['price']);
} else {
$tax = false;
}
 
if ($this->config->get('config_review_status')) {
$rating = (int)$result['rating'];
} else {
$rating = false;
}
 
$this->data['products'][] = array(
'product_id'  => $result['product_id'],
'thumb'       => $image,
'thumbwidth'  => $imagewidth,
'thumbheight' => $imageheight,
'name'        => $result['name'],
'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 300),
/*'description_mini' => utf8_substr(strip_tags(html_entity_decode($result['description_mini'], ENT_QUOTES, 'UTF-8')), 0, 15),*/
'description_mini' => html_entity_decode ($result['description_mini']),
'price'       => $price,
'special'     => $special,
'tax'         => $tax,
'rating'      => $result['rating'],
'reviews'     => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
'href'        => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url)
);
}
 
$url = '';
 
if (isset($this->request->get['filter'])) {
$url .= '&filter=' . $this->request->get['filter'];
}
 
if (isset($this->request->get['coolfilter'])) {
$url .= '&coolfilter=' . $this->request->get['coolfilter'];
}
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
if (isset($this->request->get['coolfilter'])) {
$url .= '&coolfilter=' . $this->request->get['coolfilter'];
}
 
$this->data['sorts'] = array();
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_default'),
'value' => 'p.sort_order-ASC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.sort_order&order=ASC' . $url)
);
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_name_asc'),
'value' => 'pd.name-ASC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=pd.name&order=ASC' . $url)
);
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_name_desc'),
'value' => 'pd.name-DESC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=pd.name&order=DESC' . $url)
);
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_price_asc'),
'value' => 'p.price-ASC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.price&order=ASC' . $url)
); 
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_price_desc'),
'value' => 'p.price-DESC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.price&order=DESC' . $url)
); 
 
if ($this->config->get('config_review_status')) {
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_rating_desc'),
'value' => 'rating-DESC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=rating&order=DESC' . $url)
); 
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_rating_asc'),
'value' => 'rating-ASC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=rating&order=ASC' . $url)
);
}
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_model_asc'),
'value' => 'p.model-ASC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.model&order=ASC' . $url)
);
 
$this->data['sorts'][] = array(
'text'  => $this->language->get('text_model_desc'),
'value' => 'p.model-DESC',
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.model&order=DESC' . $url)
);
 
$url = '';
 
if (isset($this->request->get['filter'])) {
$url .= '&filter=' . $this->request->get['filter'];
}
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['coolfilter'])) {
$url .= '&coolfilter=' . $this->request->get['coolfilter'];
}
 
$this->data['limits'] = array();
 
$limits = array_unique(array($this->config->get('config_catalog_limit'), 25, 50, 75, 100));
 
sort($limits);
 
foreach($limits as $value){
$this->data['limits'][] = array(
'text'  => $value,
'value' => $value,
'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . $url . '&limit=' . $value)
);
}
 
$url = '';
 
if (isset($this->request->get['filter'])) {
$url .= '&filter=' . $this->request->get['filter'];
}
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
if (isset($this->request->get['coolfilter'])) {
$url .= '&coolfilter=' . $this->request->get['coolfilter'];
}
 
$pagination = new Pagination();
$pagination->total = $product_total;
$pagination->page = $page;
$pagination->limit = $limit;
$pagination->text = $this->language->get('text_pagination');
$pagination->url = $this->url->link('product/category', 'path=' . $this->request->get['path'] . $url . '&page={page}');
 
$this->data['pagination'] = $pagination->render();
 
$this->data['sort'] = $sort;
$this->data['order'] = $order;
$this->data['limit'] = $limit;
 
$this->data['continue'] = $this->url->link('common/home');
 
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/product/category.tpl')) {
$this->template = $this->config->get('config_template') . '/template/product/category.tpl';
} else {
$this->template = 'default/template/product/category.tpl';
}
 
$this->children = array(
'common/column_left',
'common/column_right',
'common/content_top',
'common/content_bottom',
'common/footer',
'common/header'
);
 
$this->response->setOutput($this->render());
} else {
$url = '';
 
if (isset($this->request->get['path'])) {
$url .= '&path=' . $this->request->get['path'];
}
 
if (isset($this->request->get['filter'])) {
$url .= '&filter=' . $this->request->get['filter'];
}
 
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
 
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
 
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
 
if (isset($this->request->get['limit'])) {
$url .= '&limit=' . $this->request->get['limit'];
}
 
$this->data['breadcrumbs'][] = array(
'text'      => $this->language->get('text_error'),
'href'      => $this->url->link('product/category', $url),
'separator' => $this->language->get('text_separator')
);
 
$this->document->setTitle($this->language->get('text_error'));
 
$this->data['heading_title'] = $this->language->get('text_error');
 
$this->data['text_error'] = $this->language->get('text_error');
 
$this->data['button_continue'] = $this->language->get('button_continue');
 
$this->data['continue'] = $this->url->link('common/home');
 
$this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . '/1.1 404 Not Found');
 
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/error/not_found.tpl')) {
$this->template = $this->config->get('config_template') . '/template/error/not_found.tpl';
} else {
$this->template = 'default/template/error/not_found.tpl';
}
 
$this->children = array(
'common/column_left',
'common/column_right',
'common/content_top',
'common/content_bottom',
'common/footer',
'common/header'
);
 
$this->response->setOutput($this->render());
}
}
}
?>

 

 

catalog/view/theme/*******/template/product/category.tpl

<?php echo $header; ?>
<div class="<?php if ($column_right) { ?>span9<?php } else {?>span12<?php } ?>">
<div class="row">
<div class="<?php if ($column_left or $column_right) { ?>span9<?php } ?> <?php if ($column_left and $column_right) { ?>span6<?php } ?> <?php if (!$column_right and !$column_left) { ?>span12 <?php } ?>" id="content"><?php echo $content_top; ?>
  <div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<?php echo $breadcrumb['separator']; ?><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a>
<?php } ?>
  </div>
  <h1 class="style-1"><?php echo $heading_title; ?></h1>
  <?php if ($thumb || $description) { ?>
  <div class="category-info">
<!--<?php if ($thumb) { ?>
<div class="image"><img src="<?php echo $thumb; ?>" alt="<?php echo $heading_title; ?>" /></div>
<?php } ?>-->
<?php if ($description) { ?>
<?php echo $description; ?>
<?php } ?>
</div>
  <?php } ?>
  <?php if ($categories) { ?>
  <div class="box subcat">
<div class="box-heading"><?php echo $text_refine; ?></div>
<div class="box-content">
 
<div class="box-product box-subcat">
<ul class="row"><?php $i=0;?>
<?php foreach ($categories as $category) { $i++; ?>
<?php 
if ($i%3==1) {
$a='first-in-line';
}
elseif ($i%3==0) {
$a='last-in-line';
}
else {
$a='';
}
?>
<li class="cat-height  span2">
<?php if ($category['thumb']) { ?>
<div class="image"><a href="<?php echo $category['href']; ?>"><img src="<?php echo $category['thumb']; ?>" alt="<?php echo $category['name']; ?>" /></a></div>
<?php } ?>
<div class="name subcatname"><a href="<?php echo $category['href']; ?>"><?php echo $category['name']; ?></a></div>
</li>
<?php } ?>
</ul>
</div>
</div>
  </div>
  <?php } ?>
  <?php if ($products) { ?>
  <div class="product-filter">
<div class="sort"><b><?php echo $text_sort; ?></b>
 <select onchange="location = this.value;">
<?php foreach ($sorts as $sorts) { ?>
<?php if ($sorts['value'] == $sort . '-' . $order) { ?>
<option value="<?php echo $sorts['href']; ?>" selected="selected"><?php echo $sorts['text']; ?></option>
<?php } else { ?>
<option value="<?php echo $sorts['href']; ?>"><?php echo $sorts['text']; ?></option>
<?php } ?>
<?php } ?>
 </select>
</div>
<div class="limit"><b><?php echo $text_limit; ?></b>
 <select onchange="location = this.value;">
<?php foreach ($limits as $limits) { ?>
<?php if ($limits['value'] == $limit) { ?>
<option value="<?php echo $limits['href']; ?>" selected="selected"><?php echo $limits['text']; ?></option>
<?php } else { ?>
<option value="<?php echo $limits['href']; ?>"><?php echo $limits['text']; ?></option>
<?php } ?>
<?php } ?>
 </select>
</div>
  <div class="product-compare"><a href="<?php echo $compare; ?>" id="compare-total"><?php echo $text_compare; ?></a></div>
<div class="display"><b><?php echo $text_display; ?></b> <?php echo $text_list; ?>  <a onclick="display('grid');"><?php echo $text_grid; ?></a></div>
  </div>
 
  <div class="product-grid">
<ul class="row">
<?php $i=0; foreach ($products as $product) { $i++; ?>
<?php 
if ($i%3==1) {
$a='first-in-line';
}
elseif ($i%3==0) {
$a='last-in-line';
}
else {
$a='';
}
?>
<li class="span3 <?php echo $a?>">
<?php if ($product['thumb']) { ?>
<div class="image"><a href="<?php echo $product['href']; ?>"><img id="img_<?php echo $product['product_id']; ?>" src="<?php echo $product['thumb']; ?>" title="<?php echo $product['name']; ?>" alt="<?php echo $product['name']; ?>" /></a></div>
 <?php } ?>
<div class="name"><a href="<?php echo $product['href']; ?>"><?php echo $product['name']; ?></a></div>
<div class="description"><?php echo $product['description']; ?></div>
<?php if ($product['price']) { ?>
<div class="price">
<?php if ($product['tax']) { ?>
<span class="price-tax"><?php echo $text_tax; ?> <?php echo $product['tax']; ?></span>
<?php } ?>
<?php if (!$product['special']) { ?>
<?php echo $product['price']; ?>
<?php } else { ?><span class="price-new"><?php echo $product['special']; ?></span>
<span class="price-old"><?php echo $product['price']; ?></span> 
<?php } ?>
</div>
<?php } ?>
<div class="cart-button">
<div class="cart"><a onclick="addToCart('<?php echo $product['product_id']; ?>');" class="button" title="<?php echo $button_cart; ?>"><!--<i class="icon-shopping-cart"></i>--><span><?php echo $button_cart; ?></span></a></div>
<div class="wishlist"><a class="tooltip-1 " title="<?php echo $button_wishlist; ?>"  onclick="addToWishList('<?php echo $product['product_id']; ?>');"><i class="icon-star"></i></a></div>
<div class="compare"><a class="tooltip-1" title="<?php echo $button_compare; ?>"  onclick="addToCompare('<?php echo $product['product_id']; ?>');"><i class="icon-bar-chart"></i></a></div>
<div class="clear"></div>
</div>
<div class="rating">
<?php if ($product['rating']) { ?>
<img height="13" src="catalog/view/theme/kitchen/image/stars-<?php echo $product['rating']; ?>.png" alt="<?php echo $product['reviews']; ?>" />
<?php } ?>
</div>
</li>
<?php } ?>
</ul>
  </div>
  
  <div class="pagination"><?php echo $pagination; ?></div>
  <?php } ?>
  <?php if (!$categories && !$products) { ?>
  <div class="box-container">
 <div class="content"><?php echo $text_empty; ?></div>
 <div class="buttons">
<div class="right"><a href="<?php echo $continue; ?>" class="button"><span><?php echo $button_continue; ?></span></a></div>
 </div>
  </div>
  <?php } ?>
  <?php echo $content_bottom; ?></div>
  <?php echo $column_left; ?>
</div>
</div>
<?php echo $column_right; ?>
 
<script type="text/javascript"><!--
function display(view) {
if (view == 'list') {
$('.product-grid ').attr('class', 'product-list');
$('.product-list ul').removeClass('row');
$('.product-list ul li').removeClass('span3');
$('.product-list ul li').each(function(index, element) {
html = '';
html += '<div class="row">';
var image = $(element).find('.image').html();
 
if (image != null) {
html += '<div class="image span2">' + image + '</div>';
}
html += '<div class="left span7">';
html += '<div class="name">' + $(element).find('.name').html() + '</div>';
html += '<div class="description">' + $(element).find('.description').html() + '</div>';
var price = $(element).find('.price').html();
if (price != null) {
html += '<div class="price">' + price  + '</div>';
}
html += '<div class="cart-button">';
html += '<div class="cart">' + $(element).find('.cart').html() + '</div>';
html += '<div class="wishlist">' + $(element).find('.wishlist').html() + '</div>';
html += '<div class="compare">' + $(element).find('.compare').html() + '</div>';
html += '<div class="clear">' + $(element).find('.clear').html() + '</div>';
html += '</div>';
var rating = $(element).find('.rating').html();
if (rating != null) {
html += '<div class="rating">' + rating + '</div>';
}
html += '</div>';
html += '</div>';
 
 
 
$(element).html(html);
});
 
$('.display').html('<b><?php echo $text_display; ?></b> <div id="list_b"><i class="icon-list"></i></div> <a id="grid_a" onclick="display(\'grid\');"><i class="icon-th"></i></a>');
 
$.totalStorage('display', 'list'); 
} else {
$('.product-list').attr('class', 'product-grid');
$('.product-grid ul').addClass('row');
$('.product-grid ul li').addClass('span3');
$('.product-grid ul li').each(function(index, element) {
html = '';
 
var image = $(element).find('.image').html();
 
if (image != null) {
html += '<div class="image">' + image + '</div>';
}
html += '<div class="left">';
html += '<div class="name">' + $(element).find('.name').html() + '</div>';
   html += '<div class="desc_mini">' + $(element).find('description_mini').html() + '</div>';
var price = $(element).find('.price').html();
if (price != null) {
html += '<div class="price">' + price  + '</div>';
}
html += '<div class="description">' + $(element).find('.description').html() + '</div>';
 
html += '<div class="cart-button">';
html += '<div class="cart">' + $(element).find('.cart').html() + '</div>';
html += '<div class="wishlist">' + $(element).find('.wishlist').html() + '</div>';
html += '<div class="compare">' + $(element).find('.compare').html() + '</div>';
html += '<div class="clear">' + $(element).find('.clear').html() + '</div>';
html += '</div>';
var rating = $(element).find('.rating').html();
 
if (rating != null) {
html += '<div class="rating">' + rating + '</div>';
}
 
html += '</div>';
$(element).html(html);
});
 
$('.display').html('<b><?php echo $text_display; ?></b> <a id="list_a" onclick="display(\'list\');"><i class="icon-list"></i></a>  <div id="grid_b"><i class="icon-th"></i></i></div>');
 
$.totalStorage('display', 'grid');
}
if ($('body').width() > 940) {
// tooltip demo
$('.tooltip-toggle').tooltip({
selector: "a[data-toggle=tooltip]"
})
$('.tooltip-1').tooltip({
placement:'bottom'
})
$('.tooltip-2').tooltip({
placement:'top'
})
}
 
}
 
view = $.totalStorage('display');
 
if (view) {
display(view);
} else {
display('grid');
}
//--></script> 
<!--<script type="text/javascript">
(function($){$.fn.equalHeights=function(minHeight,maxHeight){tallest=(minHeight)?minHeight:0;this.each(function(){if($(this).height()>tallest){tallest=$(this).height()}});if((maxHeight)&&tallest>maxHeight)tallest=maxHeight;return this.each(function(){$(this).height(tallest)})}})(jQuery)
$(window).load(function(){
if($(".cat-height").length){
$(".cat-height").equalHeights()}
})
</script>-->
 
<?php echo $footer; ?>

 

 

Буду весьма благодарен за помощь.

Share this post


Link to post
Share on other sites

catalog/controller/product/category.php

заменить:

'description_mini' => html_entity_decode ($result['description_mini']),

на:

'description_mini' => html_entity_decode($result['description_mini'], ENT_QUOTES, 'UTF-8'),

 

catalog/view/theme/*******/template/product/category.tpl

после:

<div class="description"><?php echo $product['description']; ?></div>

добавить:

<div class="description_mini"><?php echo $product['description_mini']; ?></div>

 

убрать:

html += '<div class="desc_mini">' + $(element).find('description_mini').html() + '</div>';

 

в 2-х местах, после:

html += '<div class="name">' + $(element).find('.name').html() + '</div>';

добавить:

html += '<div class="description_mini">' + $(element).find('.description_mini').html() + '</div>';

 

в CSS добавить стили :

.product-list .description_mini {

display: none;

}

Share this post


Link to post
Share on other sites

shchs Спасибо большое. Помогло. Логика понятна.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
You are posting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Content

    • By SergeTkach
      900.00 руб
      Скачать/Купить дополнение


      SEO Tags Generator — автогенерация SEO-тегов для OpenCart 2.x & 3.x
      Модуль обеспечивает автоматическую SEO оптимизацию мета-тегов всех категорий и товаров, что имеет большое значение для SEO продвижения интернет-магазинов. Он избавляет Вас от лишней рутины при добавлении товаров. Модуль SEO Tags Generator делает работу с OpenCart проще и комфортнее, что приближает эту CMS к принципам дружелюбного к пользователю движка сайта.
       
      Сделав простую настройку 1 раз, Вы автоматически оптимизируете тысячи страниц 1 махом, по приемлемым для поисковых систем правилам.
       
      Замечу, что такой подход полностью отвечает официальным рекомендациям гугла, которые вы можете прочитать вот тут - https://support.google.com/webmasters/answer/35624?hl=ru (см пункт "Создавая описания, используйте автоматические средства", хотя прочтение всей инструкции от Google будет тоже весьма полезным).
       
       
       
      Преимущества модуля
       
       
      Генерация мета-тегов на лету в момент формирования страницы. По сути, это можно назвать "перезапись мета-тегов". Это позволяет избежать излишней нагрузки на сервер, когда генерация идет сразу для всех товаров с сохранением мета-тегов в базу данных. И благодаря такому подходу нет необходимости генерить что-то заново после очередного добавления ( импорта товара ). 1 раз настроил формулы и забыл. Поддержка мультиязычности Интеграция с модулем CityManager Pro (раньше назывался GeoIP PRO) Возможность задать отдельные настройки формул для отдельной категории, которая выбивается из общей массы. См вкладку "SEO Tags Generator: настройки для категории" (в версиях модуля до 3.0.0 называется "SEO-формулы") Возможность обозначить в мета-тегах тайтл и дескрипшн категории минимальную и максимальную цену товаров из данной категории. А также отобразить кол-во товаров в данной категории. Нумерация пейджинации страниц категории и производителя (<if>( [page_number] ) - страница [page_number] </endif>) Генерация типичных текстов в конец или в начало описания категорий, товаров, производителей. Отличный вариант, если в момент какой-то акции, Вам нужно дописать типичное сообщение к любому описанию с призывом к действию и упоминанием текущего праздника. Или же вы можете дописать сообщение о бесплатной доставке, срочной акции, о кол-во продаж этого товара и т.д. Примеры формул составления автоматические генерируемых мета-тегов прилагаются в файле с архивом модуля Накопительные скидки за повторные покупки  
      Отдельно для товаров
      Возможность обозначить в мета-тегах товаров цену со скидкой, если скидка назначена (Купить <if>([special]) по акционной цене: [special] <else> за [price]) Возможность указать в мета-тегах товаров кол-во отзывов и рейтинг данного товара, кол-во покупок Возможность добавить значимые атрибуты в мета-теги. См переменную [attribute index="1"] Возможность собрать название родительской категории по цепочке вложения с неполными названиями (будет интересно для тех сайтов, где категории названы коротко. К примеру: Велосипеды -> Горные -> Титановые) можно превратить в текст "Титановые горные велосипеды" с помощью переменной [category_nested] Функции для преобразования текста: привести к ВЕРХНЕМУ РЕГИСТРУ или к нижнему регистру, вырезать из названия товара какие-либо ненужные слова Список всех переменных модуля SEO Tags Generator смотрите в едином месте на моем сайте - http://sergetkach.com/seo-tags-generator-variables/  
       
      Недостатки модуля
       
      Модуль не поможет Вам с экспортом мета-тегов куда либо вне Вашего сайта! Для таких целей, лучше использовать модули, которые генерируются мета-теги в базу данных. Но забудьте тогда о таких динамических переменных, как цена, акционная цена, кол-во продаж, отзывов для товара, пейджинация и цены от x для категорий.
       
       
       
      Функционал дополнительных расширений
       
      Генерация SEO URL делается через родственный модуль — SEO URL Generator FREE Отмена ввода мета-тега title (в папке "Дополнительные-модификаторы/title" ) Готовый модификатор для совмещения с модулем GeoIp Pro (модификатора STG_group_in_meta_tags-for-2.0.x.ocmod.xml в папке "Дополнительные-модификаторы"). Ввод тега H1 для чистого OpenCart, в ocStore и OpenCart PRO и так есть (в папке "Дополнительные-модификаторы/tag-h1-for-OpenCart-only" )  
       
       
      * Внимание!
       
       
      Покупая модуль, Вы даете свое согласие с ЛИЦЕНЗИОННЫМ СОГЛАШЕНИЕМ, которое представлено внизу этого текста. Также Вы соглашаетесь с моей Политикой поддержки! Изучите ТЕХНИЧЕСКИЕ ТРЕБОВАНИЯ ниже по тексту Просьба при покупке модуля указывать домен, для которого покупается модуль. Также при необходимости, укажите отладочный локальный домен (*.loc) или поддомен на основном сайте.  
       
       
       
      Демо модуля

      Демо админки:
      http://seo-tags-generator-ru.sergetkach.com/ (!) Разрешено внесение изменений в настройки модуля, в товары и категорий (!) Логин/Пароль: demo/demo  
       
      Демо витрины:
      Категория с общей формулой, Товар с общей формулой; Проверяйте мета-теги на витрине с помощью сайтов
      http://www.exadium.com/tools/metadata/ и ему подобные А также в админке при просмотре товаров и категорий также будут видны сгенерированные мета-описания.
       
       
       
       
       
      Примеры сайтов, где работает модуль
       
      https://imperia-pechei.ru/
      https://erofly.ru/
      https://decozy.ru/
      https://www.happylight.com.ua/
      https://aimeshop.ru/
      https://mobistyle.by/
      https://techno-azbuka.ru/
      https://arvim.ru/
      https://palitra360.ru/
      https://mtbt.ru/
      https://lovo.com.ua/
      http://системы-доступа.рф/
      https://shopiums.ru/
      https://stroika-prof24.ru/

       
       
       
      Совместимость
       
      Работает на ветке 2.х начиная с версии OpenCart 2.1.0.1 (ocStore 2.1.0.1)
      Начиная с версии модуля 3.0.0 работает на ветке 3.x (OpenCart 3.0.2.0 и ocStore 3.0.2.0)
       
       
       
      Технические требования
       
      На сервере (хостинге) должно быть:
      PHP 5.4 + IonСube Loader 5
      PHP 5.6 - PHP 7.3 c IonСube Loader 10
      Внимание! PHP 7.4 пока что не поддерживается!
       
      Требования к системе OpenCart
      Работоспособность модуля проверяется на только что установленной системе без кучи других модулей. Предусмотреть все изменения, которые делают другие модули невозможно, поэтому конфликты с другими модулями не являются ошибкой в самом модуле и требуют дополнительно кастомизации (отладки), что обычно ложится на плечи разработчика магазина. Претензии по ошибкам, возникшим в результате конфликта совместимости модулей в бесплатную поддержку модуля не входят.
      Допускается проверка работоспособности модуля с установленным модулем SEO PRO и LocalCopy.ocmod.xml
       
      Что в модуле зашифровано?
      Контроллер админки модуля Библиотека модуля, где происходит проверка лицензии и служебные операции  
       
       
       
       
      Установка модуля
       
      Установка стандартная - через менеджер расширений OCMOD и описана в файле Установка-Модуля.txt (или install.txt) в архиве с модулем.
       

       
       
       
      Альтернативный модуль для генерации мета-тегов с сохранением в базу данных
       
      Вы также можете использовать для автоматическое генерации мета-тегов title и description другой мой модуль, которые является мега-комбайном по массовому редактированию товаров. И в нем как раз есть такая возможность сгенерировать мета-теги именно в базу данных, вместо перезаписи их на лету в момент формирования страницы.
       
       
       
       
       

       
       
      Лицензионное соглашение
       
      Покупая или устанавливая новую версию данного продукта, Вы подтверждаете свое безоговорочное согласие со следующими условиями его использования.
       
      Модуль продается и используется на условиях "Как есть". Модуль представляет собой типичное решение типичной задачи. Проверяйте наличие нужного функционала в демо модуля. В стоимость модуля не входит адаптация продукта под индивидуальные нужды покупателя. Вам предоставляется неэксклюзивное право на использование модуля на 1 домене. "Перенос" лицензии на другой домен не предполагается. Однако, дополнительная лицензия может быть выдана на отладочные домены, которые соответствуют следующим требованиям:
      - Поддомен на основном домене (test.sitename.com, demo.sitename.com)
      - Поддомен на сайте разработчика (студии) (shopname.studioname.com)
      - Локальный домен вида sitename.loc или sitename.local Срок отправки кода лицензии — в течение 1 рабочего дня! Интерфейс текущей версии модуля может немного отличаться от того, который представлен на снимках экрана в презентационных материалах. Это не является дефектом модуля, просто в новых версиях модуля могут быть добавлены новые функции. Однако общие принципы работы модуля остаются теми же самыми. В случае использования мультимагазина, лицензия выдается на основной домен, на котором будет осуществляться управления всеми магазинами. Автор  дает полную гарантию, что весь заявленный функционал, кроме экспериментального, будет работать на тех версиях системы, что заявлены в разделе СОВМЕСТИМОСТЬ и при условии соблюдения ТЕХНИЧЕСКИХ ТРЕБОВАНИЙ. В случае неработоспособности из-за ошибок в модуле, обязуется исправить ее в течение 3 рабочих дней с момент получения сообщения об ошибке или в противном случае осуществить возврат с вычетом комиссий платежных систем. Гарантия устранения ошибок действует 12 месяцев с момента оплаты. Гарантия НЕ РАСПРОСТРАНЯЕТСЯ на Дополнительные модификаторы(!) из папки "Дополнительные-модификаторы" (раннее называлась "additional"). Они являются бонусными и не входят в стоимость покупки. Вы теряете гарантию на бесплатную поддержку, если в модуле были сделаны модификации (не зависимо делал ли их я или сторонний разработчик, модуль перестает работать по типичному сценарию и требует индивидуального рассмотрения ситуации) Гарантия устранения ошибок не распространяется на конфликты совместимости модулей. То есть, говорить, что проблема точно исходит из моего модуля можно только в том случае, если на сайте не установлен ни один другой модуль ( кроме LocalCopy.ocmod.xml ) и при этом исходные файлы OpenCart не были отредактированы вручную. Гарантия не распространяется на новый экспериментальный функционал, который появляется при выпуске бета-версии модуля (добавляется слово Бета-версия после номера версии) Покупая и продолжая использовать модуль Вы соглашаетесь с "Политикой поддержки" При оценке возможного ущерба от использования купленного программного обеспечения, в котором была ошибка, максимальная ответственность автора и (или) продавца не может превышать стоимость дефектного ПО, которую покупатель оплатил по факту. Автор оставляет за собой право отказывать в поддержке в случае, если клиент не соблюдает рамки приличия и деловой стиль общения и/или позволяет себе фамильярность, оскорбления или хамство Модуль содержит зашифрованные файлы, обеспечивающие контроль над лицензиями Вы отказываетесь от намерения запрашивать открытый исходный код зашифрованных файлов и осознаете, что любая попытка расшифровки файлов или иного взлома модуля является незаконной Если Вы планируете дорабатывать модуль, необходимо получить согласие автора модуля на такие доработки. (Зачастую я не против внесения изменений в открытый код модуля, но формулировка "купил модуль с надеждой доработать, а тут закрыто" не является основанием для возврата.) Результаты платной доработки модуля могут включаться в следующие версии без получения согласия от клиента, оплатившего такую доработку.

       
       
      Также рекомендую следующие модули
       
       
      Для снижения рутины во время SEO-оптимизации я также подготовил модуль автоматической генерации SEO URL, 
      который массово генерирует ЧПУ для товаров, у которых их нет (к примеру, импортированные из 1С).
      Для массового редактирования товаров - Handy Product Manager.
       
      Добавил SergeTkach Добавлено 03.04.2017 Категория SEO, карта сайта, оптимизация Системные требования PHP 5.4 + IonСube Loader 5 или PHP 5.6 - 7.3 + IonСube Loader 10. Внимание! PHP 7.3 пока что не поддерживается! Метод активации По запросу в ЛС
      По запросу на почту Ioncube Loader Требуется OpenCart 3.0
      2.3
      2.2
      2.1 ocStore 3.0
      2.3
      2.2
      2.1 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1 Обращение к серверу разработчика Нет Старая цена 0  
    • By SergeTkach
      Модуль обеспечивает автоматическую SEO оптимизацию мета-тегов всех категорий и товаров, что имеет большое значение для SEO продвижения интернет-магазинов. Он избавляет Вас от лишней рутины при добавлении товаров. Модуль SEO Tags Generator делает работу с OpenCart проще и комфортнее, что приближает эту CMS к принципам дружелюбного к пользователю движка сайта.
       
      Сделав простую настройку 1 раз, Вы автоматически оптимизируете тысячи страниц 1 махом, по приемлемым для поисковых систем правилам.
       
      Замечу, что такой подход полностью отвечает официальным рекомендациям гугла, которые вы можете прочитать вот тут - https://support.google.com/webmasters/answer/35624?hl=ru (см пункт "Создавая описания, используйте автоматические средства", хотя прочтение всей инструкции от Google будет тоже весьма полезным).
       
       
       
      Преимущества модуля
       
       
      Генерация мета-тегов на лету в момент формирования страницы. По сути, это можно назвать "перезапись мета-тегов". Это позволяет избежать излишней нагрузки на сервер, когда генерация идет сразу для всех товаров с сохранением мета-тегов в базу данных. И благодаря такому подходу нет необходимости генерить что-то заново после очередного добавления ( импорта товара ). 1 раз настроил формулы и забыл. Поддержка мультиязычности Интеграция с модулем CityManager Pro (раньше назывался GeoIP PRO) Возможность задать отдельные настройки формул для отдельной категории, которая выбивается из общей массы. См вкладку "SEO Tags Generator: настройки для категории" (в версиях модуля до 3.0.0 называется "SEO-формулы") Возможность обозначить в мета-тегах тайтл и дескрипшн категории минимальную и максимальную цену товаров из данной категории. А также отобразить кол-во товаров в данной категории. Нумерация пейджинации страниц категории и производителя (<if>( [page_number] ) - страница [page_number] </endif>) Генерация типичных текстов в конец или в начало описания категорий, товаров, производителей. Отличный вариант, если в момент какой-то акции, Вам нужно дописать типичное сообщение к любому описанию с призывом к действию и упоминанием текущего праздника. Или же вы можете дописать сообщение о бесплатной доставке, срочной акции, о кол-во продаж этого товара и т.д. Примеры формул составления автоматические генерируемых мета-тегов прилагаются в файле с архивом модуля Накопительные скидки за повторные покупки  
      Отдельно для товаров
      Возможность обозначить в мета-тегах товаров цену со скидкой, если скидка назначена (Купить <if>([special]) по акционной цене: [special] <else> за [price]) Возможность указать в мета-тегах товаров кол-во отзывов и рейтинг данного товара, кол-во покупок Возможность добавить значимые атрибуты в мета-теги. См переменную [attribute index="1"] Возможность собрать название родительской категории по цепочке вложения с неполными названиями (будет интересно для тех сайтов, где категории названы коротко. К примеру: Велосипеды -> Горные -> Титановые) можно превратить в текст "Титановые горные велосипеды" с помощью переменной [category_nested] Функции для преобразования текста: привести к ВЕРХНЕМУ РЕГИСТРУ или к нижнему регистру, вырезать из названия товара какие-либо ненужные слова Список всех переменных модуля SEO Tags Generator смотрите в едином месте на моем сайте - http://sergetkach.com/seo-tags-generator-variables/  
       
      Недостатки модуля
       
      Модуль не поможет Вам с экспортом мета-тегов куда либо вне Вашего сайта! Для таких целей, лучше использовать модули, которые генерируются мета-теги в базу данных. Но забудьте тогда о таких динамических переменных, как цена, акционная цена, кол-во продаж, отзывов для товара, пейджинация и цены от x для категорий.
       
       
       
      Функционал дополнительных расширений
       
      Генерация SEO URL делается через родственный модуль — SEO URL Generator FREE Отмена ввода мета-тега title (в папке "Дополнительные-модификаторы/title" ) Готовый модификатор для совмещения с модулем GeoIp Pro (модификатора STG_group_in_meta_tags-for-2.0.x.ocmod.xml в папке "Дополнительные-модификаторы"). Ввод тега H1 для чистого OpenCart, в ocStore и OpenCart PRO и так есть (в папке "Дополнительные-модификаторы/tag-h1-for-OpenCart-only" )  
       
       
      * Внимание!
       
       
      Покупая модуль, Вы даете свое согласие с ЛИЦЕНЗИОННЫМ СОГЛАШЕНИЕМ, которое представлено внизу этого текста. Также Вы соглашаетесь с моей Политикой поддержки! Изучите ТЕХНИЧЕСКИЕ ТРЕБОВАНИЯ ниже по тексту Просьба при покупке модуля указывать домен, для которого покупается модуль. Также при необходимости, укажите отладочный локальный домен (*.loc) или поддомен на основном сайте.  
       
       
       
      Демо модуля

      Демо админки:
      http://seo-tags-generator-ru.sergetkach.com/ (!) Разрешено внесение изменений в настройки модуля, в товары и категорий (!) Логин/Пароль: demo/demo  
       
      Демо витрины:
      Категория с общей формулой, Товар с общей формулой; Проверяйте мета-теги на витрине с помощью сайтов
      http://www.exadium.com/tools/metadata/ и ему подобные А также в админке при просмотре товаров и категорий также будут видны сгенерированные мета-описания.
       
       
       
       
       
      Примеры сайтов, где работает модуль
       
      https://imperia-pechei.ru/
      https://erofly.ru/
      https://decozy.ru/
      https://www.happylight.com.ua/
      https://aimeshop.ru/
      https://mobistyle.by/
      https://techno-azbuka.ru/
      https://arvim.ru/
      https://palitra360.ru/
      https://mtbt.ru/
      https://lovo.com.ua/
      http://системы-доступа.рф/
      https://shopiums.ru/
      https://stroika-prof24.ru/

       
       
       
      Совместимость
       
      Работает на ветке 2.х начиная с версии OpenCart 2.1.0.1 (ocStore 2.1.0.1)
      Начиная с версии модуля 3.0.0 работает на ветке 3.x (OpenCart 3.0.2.0 и ocStore 3.0.2.0)
       
       
       
      Технические требования
       
      На сервере (хостинге) должно быть:
      PHP 5.4 + IonСube Loader 5
      PHP 5.6 - PHP 7.3 c IonСube Loader 10
      Внимание! PHP 7.4 пока что не поддерживается!
       
      Требования к системе OpenCart
      Работоспособность модуля проверяется на только что установленной системе без кучи других модулей. Предусмотреть все изменения, которые делают другие модули невозможно, поэтому конфликты с другими модулями не являются ошибкой в самом модуле и требуют дополнительно кастомизации (отладки), что обычно ложится на плечи разработчика магазина. Претензии по ошибкам, возникшим в результате конфликта совместимости модулей в бесплатную поддержку модуля не входят.
      Допускается проверка работоспособности модуля с установленным модулем SEO PRO и LocalCopy.ocmod.xml
       
      Что в модуле зашифровано?
      Контроллер админки модуля Библиотека модуля, где происходит проверка лицензии и служебные операции  
       
       
       
       
      Установка модуля
       
      Установка стандартная - через менеджер расширений OCMOD и описана в файле Установка-Модуля.txt (или install.txt) в архиве с модулем.
       

       
       
       
      Альтернативный модуль для генерации мета-тегов с сохранением в базу данных
       
      Вы также можете использовать для автоматическое генерации мета-тегов title и description другой мой модуль, которые является мега-комбайном по массовому редактированию товаров. И в нем как раз есть такая возможность сгенерировать мета-теги именно в базу данных, вместо перезаписи их на лету в момент формирования страницы.
       
       
       
       
       

       
       
      Лицензионное соглашение
       
      Покупая или устанавливая новую версию данного продукта, Вы подтверждаете свое безоговорочное согласие со следующими условиями его использования.
       
      Модуль продается и используется на условиях "Как есть". Модуль представляет собой типичное решение типичной задачи. Проверяйте наличие нужного функционала в демо модуля. В стоимость модуля не входит адаптация продукта под индивидуальные нужды покупателя. Вам предоставляется неэксклюзивное право на использование модуля на 1 домене. "Перенос" лицензии на другой домен не предполагается. Однако, дополнительная лицензия может быть выдана на отладочные домены, которые соответствуют следующим требованиям:
      - Поддомен на основном домене (test.sitename.com, demo.sitename.com)
      - Поддомен на сайте разработчика (студии) (shopname.studioname.com)
      - Локальный домен вида sitename.loc или sitename.local Срок отправки кода лицензии — в течение 1 рабочего дня! Интерфейс текущей версии модуля может немного отличаться от того, который представлен на снимках экрана в презентационных материалах. Это не является дефектом модуля, просто в новых версиях модуля могут быть добавлены новые функции. Однако общие принципы работы модуля остаются теми же самыми. В случае использования мультимагазина, лицензия выдается на основной домен, на котором будет осуществляться управления всеми магазинами. Автор  дает полную гарантию, что весь заявленный функционал, кроме экспериментального, будет работать на тех версиях системы, что заявлены в разделе СОВМЕСТИМОСТЬ и при условии соблюдения ТЕХНИЧЕСКИХ ТРЕБОВАНИЙ. В случае неработоспособности из-за ошибок в модуле, обязуется исправить ее в течение 3 рабочих дней с момент получения сообщения об ошибке или в противном случае осуществить возврат с вычетом комиссий платежных систем. Гарантия устранения ошибок действует 12 месяцев с момента оплаты. Гарантия НЕ РАСПРОСТРАНЯЕТСЯ на Дополнительные модификаторы(!) из папки "Дополнительные-модификаторы" (раннее называлась "additional"). Они являются бонусными и не входят в стоимость покупки. Вы теряете гарантию на бесплатную поддержку, если в модуле были сделаны модификации (не зависимо делал ли их я или сторонний разработчик, модуль перестает работать по типичному сценарию и требует индивидуального рассмотрения ситуации) Гарантия устранения ошибок не распространяется на конфликты совместимости модулей. То есть, говорить, что проблема точно исходит из моего модуля можно только в том случае, если на сайте не установлен ни один другой модуль ( кроме LocalCopy.ocmod.xml ) и при этом исходные файлы OpenCart не были отредактированы вручную. Гарантия не распространяется на новый экспериментальный функционал, который появляется при выпуске бета-версии модуля (добавляется слово Бета-версия после номера версии) Покупая и продолжая использовать модуль Вы соглашаетесь с "Политикой поддержки" При оценке возможного ущерба от использования купленного программного обеспечения, в котором была ошибка, максимальная ответственность автора и (или) продавца не может превышать стоимость дефектного ПО, которую покупатель оплатил по факту. Автор оставляет за собой право отказывать в поддержке в случае, если клиент не соблюдает рамки приличия и деловой стиль общения и/или позволяет себе фамильярность, оскорбления или хамство Модуль содержит зашифрованные файлы, обеспечивающие контроль над лицензиями Вы отказываетесь от намерения запрашивать открытый исходный код зашифрованных файлов и осознаете, что любая попытка расшифровки файлов или иного взлома модуля является незаконной Если Вы планируете дорабатывать модуль, необходимо получить согласие автора модуля на такие доработки. (Зачастую я не против внесения изменений в открытый код модуля, но формулировка "купил модуль с надеждой доработать, а тут закрыто" не является основанием для возврата.) Результаты платной доработки модуля могут включаться в следующие версии без получения согласия от клиента, оплатившего такую доработку.

       
       
      Также рекомендую следующие модули
       
       
      Для снижения рутины во время SEO-оптимизации я также подготовил модуль автоматической генерации SEO URL, 
      который массово генерирует ЧПУ для товаров, у которых их нет (к примеру, импортированные из 1С).
      Для массового редактирования товаров - Handy Product Manager.
       
    • By sdlmarket
      Добрый день!
      Пользуюсь вашим продуктом.
      Подскажите, пожалуйста, как парсить мета тег description
    • By A132
      День добрый, господа!
       
      Вопрос такой: есть описание категорий. Для каждой категории оно разное - для одних длинное, для других короткое. И длинные описания плохо сказываются на удобстве просмотра страницы. Поэтому очень бы хотелось, чтобы была возможность эти описания сворачивать и разворачивать по клику.
      Такой модуль существует (во вложении). Но проблема этого модуля в том, что длину текста до свёртывания он берёт, как постоянную величину, и если реальное описание в конкретной категории короче этой величины, то получается, что модуль наоборот оставляет там после текста пустое место (картинки с примерами во вложении).
      Как связаться с автором мода я не знаю, поэтому вопрос к знатокам - может уже есть улучшенный, или есть возможность улучшить этот модуль так, чтобы он сворачивал не все тексты подряд, а только те, которые длинней определённого значения?


      category_description_expand_collapse.ocmod.xml
    • By Sunser
      300.00 руб
      Скачать/Купить дополнение


      Ease description - модуль упрощенного описания
      Ease description - модуль упрощенного описания для Opencart и ocStore.
       
      Расширение подходит и тестировалось на версиях Opencart 2.0, 2.1, 2.2, 2.3 и 3.0
      Так же подойдет для OpencartPro версии 2.1 и 2.3
      Расширение подходит и тестировалось на версиях ocStore 2.1, 2.3 и 3.0
      Расширение тестировалось на официальных версиях, скачанных из официальных сайтов сборок.
      Модуль тестировался по нескольких раз на всех выше указанных версиях сайта. Так же модуль проверялся на ошибки.
       
      -- Установка расширения:
      Есть два способа установки:
      1) Это просто откройте установщик расширений и выберите данное расширение под версию вашей сборки и установите, после чего обновите "Модификаторы", Потом перейдите в раздел Модулей и активируйте его, после чего настройте как вам необходимо. После настройки и сохранения модуля, перейдите в макеты или схемы и выберите место где вы хотите что бы модуль выводился и сохраните. После чего модуль появится на сайте;
      2) Распакуйте файл с версией вашего Opencart или ocStore и перетащите в корень вашего сайта. После чего обновите "Модификаторы", потом перейдите в раздел Модулей и активируйте его, после чего настройте как вам необходимо.
      Модуль не заменяет никаких файлов.
       
      -- Что может модуль:
      1) Модуль мультиязычный;
      2) Модуль выводит любой текст и заголовок на сайте, который вы можете редактировать как вам будет удобно;
      3) В модуле можно задавать ширину блока;
      4) В блоке есть настройка, при которой блок скрывается, если его нет в поле видимости, типа lazyload;
      5) В модуле можно выводить кнопку "показать еще";
      6) В модуле можно задавать скролл для текста
      7) Так же можно задавать стили для кнопки "показать еще";
      Зачем нужен этот модуль и как он работает?
      Модуль позволяет гибко, быстро и удобно настраивать вывод блоков с текстом на сайте.
      Например вам нужно на главной странице вывести блок с заголовком и текстом. С такой задачей может с легкостью справится модуль "Текстовый блок - HTML".
      Но а если вам нужно что бы на модуле была кнопка "загрузить еще", что бы при нажатии показывался весь текст. Или же вам надо что бы на модуле был скролл определенной высоты или задать ширину блока. То тогда нужно обращаться к программистам что бы дописывал функционал.
      А в данном модуле уже все сделано и займет немного времени в настройке и выводе.
       
      Модуль легкий в настройке.
      Модуль имеет 14 полей:
      1) Название модуля - тут просто пишите название модуля, оно будет отображаться в админке вашего сайта;
      2) Кнопка "Загрузить еще" - Она отвечает будет ли на блоке с текстом кнопка "показать еще";
      3) Высота блока для загрузить еще - отвечает за высоту блока, после которой появится кнопка "показать еще";
      4) Затухнение блока при кнопке "Загрузить еще" - отвечает за затухнение текста перед кнопкой "показать еще";
      5) Расположение кнопка "Загрузить еще" - отвечает за расположение кнопки "показать еще";
      6) Текст кнопки До нажатия - тут можно задать название кнопки "показать еще", по стандарту, если поле пустое, то выводится стандартный текст;
      7) Текст кнопки После нажатия - тут можно задать название кнопки "скрыть", по стандарту, если поле пустое, то выводится стандартный текст;
      8) Блок со скроллом - отвечает за то будет скрол на тексте или нет;
      9) Высота блока для скролла - задается высота для блока со скроллом;
      10) Умное появление - lazyload;
      11) Ширина блока с описанием - тут задается ширина блока с текстом, если поле равно 0, то ширина блока равна 100%;
      12) Статус - оно отвечает, будет работать модуль или нет на сайте.
      13) Заголовок - тут задается заголовок;
      14) Описание - тут задается описание
       
      Если вы заметите какие-то неполадки или у вас будет предложение по улучшению самого модуля, пишите в личное сообщения данного сервиса, после чего я вам обязательно отвечу.
      Добавил Sunser Добавлено 28.10.2019 Категория Модули Системные требования Сайт разработчика Метод активации Без активации Ioncube Loader Нет OpenCart 3.0
      2.3
      2.2
      2.1
      2.0 ocStore 3.0
      2.3
      2.1 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1 Обращение к серверу разработчика Нет Старая цена  
  • Recently Browsing   0 members

    No registered users viewing this page.

×

Important Information

On our site, cookies are used and personal data is processed to improve the user interface. To find out what and what personal data we are processing, please go to the link. If you click "I agree," it means that you understand and accept all the conditions specified in this Privacy Notice.