Доброго времени суток!
В одном из наших проектов клиент попросил добавить возможность загружать различные документы (сертификаты, лицензии и так далее), привязывая их к странице производителя и дать возможность скачивать их всем посетителям сайта.
Как вы знаете, Opencart умеет прикреплять файлы, но совершенно для других целей. Во-первых, файлы крепятся к продуктам. Во-вторых, скачиваются через раздел "Мои загрузки" личного кабинета клиента. Товар должен быть приобретен, чтобы файлы отобразились в загрузках.
Таким образом, текущее решение не устравивает. Поиск в интернете также не принес ничего дельного, поэтому расчехляем исходный код OpenCart и пишем свой модуль.
Для нетерпеливых - репозиторий с готовым кодом.
Что получилость в итоге.
Административная часть
Публичная часть
В этом примере используется чистая версия OpenCart 2.3.0.2
Подготовка
Для начала подготовим нашу базу данных.
Для нашей задачи нужно будет хранить несколько файлов для каждого производителя, то есть связь будет Многие-ко-многим. Создадим в базе данных новую таблицу с именем manufacturer_to_download, где будут храниться связи загруженных файлов и производителей.
create table manufacturer_to_download (
manufacturer_id INTEGER,
download_id INTEGER
)
Теперь напишем административную часть нашего модуля.
OpenCart не сложен по своей структуре и реализует обычный паттерн MVC, но с добавлением L (language - язык) для реализации мультиязычности. Каждый модуль разделен на несколько файлов - модель, контроллер, шаблон и языковые файлы с переводами для соответствующего языка.
Будем придерживаться этих правил и создавать всё как положено.
Начнем с модели - нужно получать доступные файлы для скачивания при получении производителя. Добавим нужный функционал.
Для этого изменим несколько строк в файле admin/model/catalog/manufacturer.php
admin / model / catalog / manufacturer.php
<?php
class ModelCatalogManufacturer extends Model {
public function addManufacturer($data) {
/***/
if (isset($data['download'])) {
foreach ($data['download'] as $download_id) {
$this->db->query("INSERT INTO " . DB_PREFIX . "manufacturer_to_download SET product_id = '" . (int)$manufacturer_id . "', download_id = '" . (int)$download_id . "'");
}
}
$this->cache->delete('manufacturer');
return $manufacturer_id;
}
public function editManufacturer($manufacturer_id, $data) {
/***/
$this->db->query("DELETE FROM " . DB_PREFIX . "manufacturer_to_download WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
if (isset($data['download'])) {
foreach ($data['download'] as $download_id) {
$this->db->query("INSERT INTO " . DB_PREFIX . "manufacturer_to_download SET manufacturer_id = '" . (int)$manufacturer_id . "', download_id = '" . (int)$download_id . "'");
}
}
$this->cache->delete('manufacturer');
}
public function deleteManufacturer($manufacturer_id) {
/***/
$this->db->query("DELETE FROM " . DB_PREFIX . "manufacturer_to_download WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
$this->cache->delete('manufacturer');
}
public function getManufacturerDownloads($id) {
$download_data = array();
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "manufacturer_to_download WHERE manufacturer_id = '" . (int)$id . "'");
foreach ($query->rows as $result) {
$download_data[] = $result['download_id'];
}
return $download_data;
}
}
admin / controller / catalog / manufacturer.php
$data['button_edit'] = $this->language->get('button_edit');
$data['button_delete'] = $this->language->get('button_delete');
+ $data['help_download'] = $this->language->get('help_download');
+ $data['entry_download'] = $this->language->get('entry_download');
+
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
admin / controller / catalog / manufacturer.php
$data['button_save'] = $this->language->get('button_save');
$data['button_cancel'] = $this->language->get('button_cancel');
+ $data['help_download'] = $this->language->get('help_download');
+ $data['entry_download'] = $this->language->get('entry_download');
+
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
Изменим метод getForm(), а также добавим метод getManufacturerDownloads($id) для получения всех загрузок производителя из БД.
admin / controller / catalog / manufacturer.php
+ // Downloads
+ $this->load->model('catalog/download');
+
+ if (isset($this->request->post['download'])) {
+ $downloads = $this->request->post['download'];
+ } elseif (isset($this->request->get['manufacturer_id'])) {
+ $downloads = $this->model_catalog_manufacturer->getManufacturerDownloads($this->request->get['manufacturer_id']);
+ } else {
+ $downloads = array();
+ }
+
+ $data['downloads'] = array();
+
+ foreach ($downloads as $download_id) {
+ $download_info = $this->model_catalog_download->getDownload($download_id);
+
+ if ($download_info) {
+ $data['downloads'][] = array(
+ 'download_id' => $download_info['download_id'],
+ 'name' => $download_info['name']
+ );
+ }
+ }
+
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput($this->load->view('catalog/manufacturer_form', $data));
}
+ public function getManufacturerDownloads($id) {
+ $download_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "manufacturer_to_download WHERE manufacturer_id = '" . (int)$id . "'");
+
+ foreach ($query->rows as $result) {
+ $download_data[] = $result['download_id'];
+ }
+
+
+ return $download_data;
+ }
+
Теперь поправим шаблон. Нам понадобится изменить файл, отвечающий за редактирование определенного производителя - admin / view / template / catalog / manufacturer_form.tpl
admin / view / template / catalog / manufacturer_form.tpl
<h3 class="panel-title"><i class="fa fa-pencil"></i> <?php echo $text_form; ?></h3>
</div>
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-manufacturer" class="form-horizontal">
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-name"><?php echo $entry_name; ?></label>
<div class="col-sm-10">
<input type="text" name="name" value="<?php echo $name; ?>" placeholder="<?php echo $entry_name; ?>" id="input-name" class="form-control" />
<?php if ($error_name) { ?>
<div class="text-danger"><?php echo $error_name; ?></div>
<?php } ?>
</div>
</div>
+
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="input-download">
+ <span data-toggle="tooltip" title="<?php echo $help_download; ?>"><?php echo $entry_download; ?></span></label>
+ <div class="col-sm-10">
+ <input type="text" name="download" value="" placeholder="<?php echo $entry_download; ?>" id="input-download" class="form-control" />
+ <div id="download" class="well well-sm" style="min-height: 150px; overflow: auto;">
+ <?php foreach ($downloads as $download) { ?>
+ <div id="download<?php echo $download['download_id']; ?>"><i class="fa fa-minus-circle"></i> <?php echo $download['name']; ?>
+ <input type="hidden" name="download[]" value="<?php echo $download['download_id']; ?>" />
+ </div>
+ <?php } ?>
+ </div>
+ </div>
+ </div>
+
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_store; ?></label>
<div class="col-sm-10">
Обязательно внизу страницы добавляем скрипты для обработки загружаемых файлов:
admin / view / template / catalog / manufacturer_form.tpl
+<script>
+// Downloads
+ $('input[name=\'download\']').autocomplete({
+ 'source': function(request, response) {
+ $.ajax({
+ url: 'index.php?route=catalog/download/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['download_id']
+ }
+ }));
+ }
+ });
+ },
+ 'select': function(item) {
+ $('input[name=\'download\']').val('');
+ $('#download' + item['value']).remove();
+ $('#download').append('<div id="download' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" name="download[]" value="' + item['value'] + '" /></div>');
+ }
+ });
+
+ $('#download').delegate('.fa-minus-circle', 'click', function() {
+ $(this).parent().remove();
+ });
+</script>
Теперь пришел черёд локализовать изменения. Сделаем в первую очередь для русского языка. Откроем файл admin / language / ru-ru / catalog / manufacturer.php и внесем необходимые правки:
admin / language / ru-ru / catalog / manufacturer.php
+ $_['entry_download'] = 'Файлы для скачивания';
+ $_['help_download'] = '(Автозаполнение)';
Теперь откроем административную часть и перейдем в раздел Производители, предварительно загрузив несколько файлов через Каталог - Загрузки.
Отлично!
Перейдем к публичной части сайта. продолжение следует...