Ruslan Brest, rb.labtodo.com
Backend web-developer: CodeIgniter, PHP, MySQL, OpenCart, PrestaShop, MaxSite CMS

Opencart 1.5.x (catalog): как в каталоге добавить вывод атрибута к описанию товара

Просмотров: 14041 RSS 11
Howto » OpenCart

В комментариях к статье об изменении длины описаний в каталоге Opencart 1.5 спросили, можно ли сделать так,

чтобы вместо описания товара в каталоге выводился определённый атрибут товара (краткое описание товара). Интересует для OpenCart 1.5.1

Это несложно, изменения в двух файлах приведены ниже.

Как можно заметить, в файле catalog/controller/product/category.php я добавил текст атрибута к описанию. Не совсем то, что просили, но если надо выводить только атрибут -- думаю, несложно догадаться, как это сделать (заменить строчку на $descr_plaintext = $result['attribute_text'];), а несколько предыдущих строк там могут быть убраны. В общем, при наличии минимальных познаний или аккуратно методом тыка это будет несложно сделать, поэтому не описываю.

Изменения базируются на моём коде, а не чистом OpenCart v1.5: в этом месте была правка, но она задокументирована в упомянутой статье и минимальна. Поэтому, думаю, проблем с нахождением места и внесением изменений не возникнет.

Требуется заменить переменную $attr_id_to_descr = 0; на идентификатор своего атрибута, который должен выводиться. Его можно найти в админ-части магазина, внимательно изучив ссылку редактирования нужного нам атрибута: в адресе после токена (token=...) присутствует переменная ...&attribute_id=9 (например). Вот этот идентификатор и надо указать вместо нуля.

diff --git a/public_html/catalog/controller/product/category.php b/public_html/catalog/controller/product/category.php
index 54ad9bc..f94cc43 100644
--- a/public_html/catalog/controller/product/category.php
+++ b/public_html/catalog/controller/product/category.php
@@ -185,6 +185,8 @@ class ControllerProductCategory extends Controller {
                                {
                                        $descr_plaintext = mb_substr($descr_plaintext, 0, $cut_descr_symbols, 'UTF-8') . ' …';
                                }
+                               if( !empty($result['attribute_text']) )
+                                       $descr_plaintext .= '<hr />' . $result['attribute_text'];
                                $this->data['products'][] = array(
                                        'product_id'  => $result['product_id'],
                                        'thumb'       => $image,
diff --git a/public_html/catalog/model/catalog/product.php b/public_html/catalog/model/catalog/product.php
index 595bfc6..2b19a72 100644
--- a/public_html/catalog/model/catalog/product.php
+++ b/public_html/catalog/model/catalog/product.php
@@ -11,13 +11,40 @@ class ModelCatalogProduct extends Model {
 			$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 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') . "'");
-		
+		$attr_id_to_descr = 0;
+		if( 0 != $attr_id_to_descr )
+		{
+			$sql_attr1 = " p.product_id AS product_id, pa.text as attribute_text, ";
+			$sql_attr2 = " LEFT JOIN " . DB_PREFIX . "product_attribute pa ON (p.product_id = pa.product_id AND pa.attribute_id=" . $attr_id_to_descr .')';
+		}
+		else
+		{
+			$sql_attr1 = "";
+			$sql_attr2 = "";
+		}
+		$query = $this->db->query("SELECT DISTINCT *, pd.name AS name, p.image, m.name AS manufacturer,". $sql_attr1
+			." (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"
+			." 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)"
+			. $sql_attr2
+			." 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'],
 				'name'             => $query->row['name'],
 				'description'      => $query->row['description'],
+				'attribute_text'   => ( (0 == $attr_id_to_descr) ? '' : $query->row['attribute_text'] ),
 				'meta_description' => $query->row['meta_description'],
 				'meta_keyword'     => $query->row['meta_keyword'],
 				'model'            => $query->row['model'],
twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru digg.com friendfeed.com liveinternet.ru livejournal.ru yandex.ru del.icio.us
Комментариев: 11
  1. Большое спасибо, все работает! Только в цитате человек имеел ввиду выод атрибута ВМЕСТО описания. Для этого, думаю, атрибут стоит не присоединять к описанию, а выводить вместо него, т.е.

    вместо строки $descr_plaintext .= '' . $result['attribute_text'];

    можно написать $descr_plaintext = $result['attribute_text'];

    А так все чОтко, респект! ;)

  2. 2011-11-10 в 11:06:26 | Ruslan Brest

    Так и задумано :) Я же специально сделал об этом оговорку: сразу после цитаты в самом начале текста. И аналогичный рецепт по изменению "после" на "вместо" там тоже указан.

    Просто описал более универсальный вариант как более интересный, а частный случай мы бы и руками поправили, если того пояснения не хватило бы. Но судя по появившейся сразу вслед за публикацией оценке и отсутствию вопросов, спрашивавшему всё оказалось понятно :)

  3. А если необходимо вывести несколько атрибутов (10), придется повторять код для каждого?

  4. 2011-12-11 в 06:14:06 | Ruslan Brest

    Нет, тогда уже лучше код менять. Чтобы выбирались сразу 10 атрибутов. Но там уже, по-моему, недостаточно будет запрос из этого примера изменить - надо будет дополнительно обрабатывать изменившиеся результаты запроса.

    Или выбирать по группе атрибутов.

    Ещё лучше взять аналогичные код со страниц вывода товара и переносить по тому же принципу в product/category. Не зная конкретную задачу, сложно сказать, как лучше сделать.

  5. 2012-01-14 в 03:07:23 | Шамиль

    Можете выложить vqmod. данный метод не работает на ocStore :(

  6. 2012-01-14 в 04:13:04 | Ruslan Brest

    На какой именно версии ocStore не работает? Это написано для версий 1.5 (соответственно ocstore от 1.0.1 и выше).

    С vqmod не помогу - я им не пользуюсь.

  7. Скажите а как сделать чтобы выводить опции товара в категории?

  8. Помогите с кодом для версии 1.5.3 Очень прошу, что бы в категориях вместо краткого описания выводить все атрибуты товара. Спасибо

  9. Здравствуйте! У меня такой вот код

    catalog\controller\product\category.php, 199

    'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 100) . '..',
         'attribute_groups' => $this->model_catalog_product->getProductAttributes($result['product_id']),
         'price'    => $price,

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

    <div class="description">
       <?php if($product['attribute_groups']) { ?>
       <table>
        <?php foreach($product['attribute_groups'] as $attribute_group) { ?>
        <thead><!--названия групп-->
        <tr>
         <td colspan="2"><?php echo $attribute_group['name']; ?></td>
        </tr>
        </thead><!---->
        <tbody>
         <?php foreach($attribute_group['attribute'] as $attribute) { ?>
        <tr>
         <td><?php echo $attribute['name']; ?></td>
         <td><?php echo $attribute['text']; ?></td>
        </tr>
         <?php } ?>
        </tbody>
        <?php } ?>
       </table>
       <?php } ?>
      </div>

    как сделать так чтобы отображались не все группы а только 1 например attribute_id=1

  10. т. е. attribute_group_id=1

  11. 2013-12-29 в 07:42:16 | Аноним

    не могли бы вы описать как добавить производителя в кратком описании категории товаров?

    (это там где выбираешь категорию появляется список товаров с кратким описанием) Нужно, что бы после названия товара указать производителя. Спасибо

Оставьте комментарий!

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Имя и сайт используются только при регистрации

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email. При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д., а также подписку на новые комментарии.

Авторизация  Facebook. MaxSiteAuth. Loginza

(обязательно)