1

Тема: Несколько производителей в карточке товара

В некоторых случаях в Опенкарт возникает необходимость указать (добавить) в карточке конкретного товара несколько производителей. Это можно сделать следующим образом:

Добавляем в админке поле для ввода дополнительных производителей (именно - дополнительных. (Поле для ввода "основного" производителя (которое существует по умолчанию) оставляем и будем использовать без изменения). В дополнительное поле данные будут заносится только по необходимости (если возникнет необходимость указать двух и более производителей). Ничего нового придумывать не будем, а просто клонируем существующее поле "Показывать в категориях" в новое поле "Производитель-#" и размещаем его сразу же после поля "Производитель".

Создаем новую таблицу "oc_product_to_manufacturer" идентичную по структуре "oc_product_to_category" (лишь изменим название одного столбца на  manufacturer_id).

Далее, модифицируем файл product.php в папке admin/model/catalog

Находим:

        if (isset($data['product_category'])) {
            foreach ($data['product_category'] as $category_id) {
                $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$category_id . "'");
            }
        }

Ниже добавляем:

        if (isset($data['product_manufacturer'])) {
            foreach ($data['product_manufacturer'] as $manufacturer_id) {
                $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_manufacturer SET product_id = '" . (int)$product_id . "', manufacturer_id = '" . (int)$manufacturer_id . "'");
            }
        }

Данный поиск с добавлением необходимо сделать 2 раза, НО при нахождении второго фрагмента кода необходимо ниже добавить следующий код:

        $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_manufacturer WHERE product_id = '" . (int)$product_id . "'");
        
        if (isset($data['product_manufacturer'])) {
            foreach ($data['product_manufacturer'] as $manufacturer_id) {
                $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_manufacturer SET product_id = '" . (int)$product_id . "', manufacturer_id = '" . (int)$manufacturer_id . "'");
            }
        }

Находим вторую строку:

        $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");

Ниже добавляем:

        $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_manufacturer WHERE product_id = '" . (int)$product_id . "'");

Находим:

            $data = array_merge($data, array('product_category' => $this->getProductCategories($product_id)));

Ниже добавляем:

            $data = array_merge($data, array('product_manufacturer' => $this->getProductManufacturers($product_id)));

Находим:

    public function getProductCategories($product_id) {
        $product_category_data = array();

        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");

        foreach ($query->rows as $result) {
            $product_category_data[] = $result['category_id'];
        }

        return $product_category_data;
    }

Ниже добавляем:

    public function getProductManufacturers($product_id) {
        $product_manufacturer_data = array();

        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_manufacturer WHERE product_id = '" . (int)$product_id . "'");

        foreach ($query->rows as $result) {
            $product_manufacturer_data[] = $result['manufacturer_id'];
        }

        return $product_manufacturer_data;
    }
Спасибо сказали: pohyist1

Поделиться

2

Re: Несколько производителей в карточке товара

Открываем product.php в папке admin/controller/catalog

Находим:

        $data['entry_manufacturer'] = $this->language->get('entry_manufacturer');

Ниже добавляем:

        $data['entry_manufacturers'] = $this->language->get('entry_manufacturers');

Находим:

        $data['help_manufacturer'] = $this->language->get('help_manufacturer');

Ниже добавляем:

        $data['help_manufacturers'] = $this->language->get('help_manufacturers');

Находим:

        // Categories
        $this->load->model('catalog/category');

        if (isset($this->request->post['product_category'])) {
            $categories = $this->request->post['product_category'];
        } elseif (isset($this->request->get['product_id'])) {
            $categories = $this->model_catalog_product->getProductCategories($this->request->get['product_id']);
        } else {
            $categories = array();
        }

ВЫШЕ добавляем:

// Manufacturers
        if (isset($this->request->post['product_manufacturer'])) {
            $manufacturers = $this->request->post['product_manufacturer'];
        } elseif (isset($this->request->get['product_id'])) {
            $manufacturers = $this->model_catalog_product->getProductManufacturers($this->request->get['product_id']);
        } else {
            $manufacturers = array();
        }
        
        $data['product_manufacturers'] = array();

        foreach ($manufacturers as $manufacturer_id) {
            $manufacturer_info = $this->model_catalog_manufacturer->getManufacturer($manufacturer_id);

            if ($manufacturer_info) {
                $data['product_manufacturers'][] = array(
                    'manufacturer_id' => $manufacturer_info['manufacturer_id'],
                    'name' => $manufacturer_info['name']
                );
            }
        }

То, что только что добавили, для себя отмечаем пока под вопросом (возможно к нему придется вернуться)



Открываем файл product.php в папке admin/language/russian/catalog
Находим:

$_['entry_manufacturer']     = 'Производитель';

Ниже добавляем:

$_['entry_manufacturers']     = 'Производитель-#';

Находим:

$_['help_manufacturer']      = '(Автозаполнение)';

Ниже добавляем:

$_['help_manufacturers']      = '(Автозаполнение)';

Открываем product_form.tpl в папке admin/view/template/catalog

Ищем:

           <div class="form-group">
                <label class="col-sm-2 control-label" for="input-manufacturer"><span data-toggle="tooltip" title="<?php echo $help_manufacturer; ?>"><?php echo $entry_manufacturer; ?></span></label>
                <div class="col-sm-10">
                  <input type="text" name="manufacturer" value="<?php echo $manufacturer ?>" placeholder="<?php echo $entry_manufacturer; ?>" id="input-manufacturer" class="form-control" />
                  <input type="hidden" name="manufacturer_id" value="<?php echo $manufacturer_id; ?>" />
                </div>
              </div>

Ниже добавляем:

              <div class="form-group">
                <label class="col-sm-2 control-label" for="input-manufacturers"><span data-toggle="tooltip" title="<?php echo $help_manufacturers; ?>"><?php echo $entry_manufacturers; ?></span></label>
                <div class="col-sm-10">
                  <input type="text" name="manufacturers" value="" placeholder="<?php echo $entry_manufacturers; ?>" id="input-manufacturers" class="form-control" />
                  <div id="product-manufacturers" class="well well-sm" style="height: 150px; overflow: auto;">
                    <?php foreach ($product_manufacturers as $product_manufacturer) { ?>
                    <div id="product-manufacturers<?php echo $product_manufacturer['manufacturer_id']; ?>"><i class="fa fa-minus-circle"></i> <?php echo $product_manufacturer['name']; ?>
                      <input type="hidden" name="product_manufacturer[]" value="<?php echo $product_manufacturer['manufacturer_id']; ?>" />
                    </div>
                    <?php } ?>
                  </div>
                </div>
              </div>
Спасибо сказали: pohyist1

Поделиться

3

Re: Несколько производителей в карточке товара

Далее ищем:

// Category
$('input[name=\'category\']').autocomplete({

ВЫШЕ одбавляем:

// Manufacturers
$('input[name=\'manufacturers\']').autocomplete({
    'source': function(request, response) {
        $.ajax({
            url: 'index.php?route=catalog/manufacturer/autocomplete&token=<?php echo $token; ?>&filter_name=' +  encodeURIComponent(request),
            dataType: 'json',            
            success: function(json) {
                response($.map(json, function(item) {
                    return {
                        label: item['name'],
                        value: item['manufacturer_id']
                    }
                }));
            }
        });
    },
    'select': function(item) {
        $('input[name=\'manufacturers\']').val('');
        
        $('#product-manufacturers' + item['value']).remove();
        
        $('#product-manufacturers').append('<div id="product-manufacturers' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" name="product_manufacturer[]" value="' + item['value'] + '" /></div>');    
    }
});

$('#product-manufacturers').delegate('.fa-minus-circle', 'click', function() {
    $(this).parent().remove();
});

Теперь обновляем кэш модификаторов и получили возможность добавлять нескольких производителей к конкретному товару.

Спасибо сказали: pohyist1

Поделиться

4

Re: Несколько производителей в карточке товара

Если мы по каким-то причинам удаляем какого-либо производителя из общего списка наших производителей, то так же необходимо  его удалить из таблицы "oc_product_to_manufacturer". Для этого открываем файл manufacturer.php из папки admin/model/catalog и ищем там код:

    public function deleteManufacturer($manufacturer_id) {
        $this->event->trigger('pre.admin.manufacturer.delete', $manufacturer_id);

        $this->db->query("DELETE FROM " . DB_PREFIX . "manufacturer WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
        $this->db->query("DELETE FROM " . DB_PREFIX . "manufacturer_to_store WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
        $this->db->query("DELETE FROM " . DB_PREFIX . "url_alias WHERE query = 'manufacturer_id=" . (int)$manufacturer_id . "'");

Ниже добавляем:

        $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_manufacturer WHERE query = 'manufacturer_id=" . (int)$manufacturer_id . "'");
Спасибо сказали: pohyist1

Поделиться

5

Re: Несколько производителей в карточке товара

Теперь выводим дополнительных производителей в карточку товара... Ищем в файле product.php из  catalog/controller/product следующий код:

        $product_info = $this->model_catalog_product->getProduct($product_id);

ВЫШЕ первого найденного совпадения добавить (код встречается в двух местах):

// Manufacturers
        $manufacturers = $this->model_catalog_product->getProductManufacturers($product_id);
        $data['product_manufacturers'] = array();

        foreach ($manufacturers as $manufact) {
            $manufacturer_info = $this->model_catalog_manufacturer->getManufacturer($manufact['manufacturer_id']);

            if ($manufacturer_info) {
                $data['product_manufacturers'][] = array(
                    'name' => $manufacturer_info['name'],
                    'href' => $this->url->link('product/manufacturer/info', 'manufacturer_id=' . $manufacturer_info['manufacturer_id'])
                );
            }
        }

Ищем в файле product.php из папки catalog/model/catalog код:

    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 getProductManufacturers($product_id) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_manufacturer WHERE product_id = '" . (int)$product_id . "'");

        return $query->rows;
    }

Ищем в файле нашего шаблона product.tpl код:

<li><?php echo $text_manufacturer; ?> <a href="<?php echo $manufacturers; ?>"><?php echo $manufacturer; ?></a></li>

Заменяем его на:

            <li><?php echo $text_manufacturer; ?> <a href="<?php echo $manufacturers; ?>"><?php echo $manufacturer; ?></a>
                    <?php foreach ($product_manufacturers as $manufact) { ?>, <a href="<?php echo $manufact['href']; ?>"><?php echo $manufact['name']; ?></a><?php } ?><br />
            </li>
Спасибо сказали: pohyist1

Поделиться

6

Re: Несколько производителей в карточке товара

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

Поделиться

7

Re: Несколько производителей в карточке товара

В данной модификации (модификация выполнялась для 2.0.1.1) пока существует один минус: если производитель отсутствует в карточке товара как "основной", а представлен только как "дополнительный", то этот товар (в производстве которого он так же принимал участие) не отображается у него на персональной странице. Это, естественно, связано с тем, что в карточке конкретного товара может быть указан только один "основной" производитель.

Как это исправить?
По логике, необходимо добавить обработку результатов таблицы  "oc_product_to_manufacturer" в том месте, где происходит обработка таблицы "oc_product" в файле manufacturer.php при выводе страницы производителя. Не разбирался, но наверно следует обратить внимание на функцию "GetProduct" (вызов - строка 180). После отработки данной функции необходимо сразу вызвать некую функцию "GetPhoductМаnufacturerAdd" которая добавит в массив недостающие продукты...(либо дополнить функцию "GetProduct" независимым кодом, который не будет влиять на на возвращаемый результат, при вызове данной функции стандартным кодом ОС)

Поделиться

8

Re: Несколько производителей в карточке товара

Спустя месяц после последнего поста пришел к выводу, что "пустые страницы" дополнительных производителей (соавторов) как-то нехорошо выглядят, если они пустые. Особенно это не радует, когда страниц соавторов скапливается через чур много (в sitemap.xml скапливается масса явно вредных (ненужных), а главное пустых (!!!) страниц). Надо исправлять ситуацию, чтобы товары соавторов отображались на их собственных страницах при поиске или при явном заходе на конкретную страницу дополнительного производителя.

Сделать это, как оказалось, совсем не сложно, хотя и стоило мне порядка 6-ти часов экспериментов над различными идеями.

Открываем в попке модели product.php, и находим там первое вхождение строки кода:

$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') . "'";

меняем на:

//        $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') . "'";
        $sql .= " LEFT JOIN " . DB_PREFIX . "product_to_manufacturer p2m ON (p.product_id = p2m.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 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') . "'";

Там же находим первое вхождение:

$sql .= " AND p.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";

меняем на:

//            $sql .= " AND p.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "'";
            $sql .= " AND (p.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "' OR p2m.manufacturer_id = '" . (int)$data['filter_manufacturer_id'] . "')";

Все. Теперь поиск по дополнительным производителям происходит как должно. На страницах любого производителя, есно, присутствуют товары, в производстве которых он участвовал.

Спасибо сказали: pohyist1

Поделиться

9

Re: Несколько производителей в карточке товара

Примеры на скринах:
1. Это основной производитель, которому мы добавили 3-х соавторов.

2. Если теперь, например, щелкнуть на соавторе Palm, то  на его странице мы увидим как и его собственные товары, так и товар, в производстве которого он участвовал ab (в данном примере это камера Canon EOS 5D... )

Спасибо сказали: pohyist1

Поделиться

10

Re: Несколько производителей в карточке товара

на счет дублей вхождений искомого кода. Нет ничего плохого, если изменить везде. Именно так я сделал для себя.

Спасибо сказали: yu.ra_89, pohyist2

Поделиться