- Свои ISO образы
- VDS с оплатой раз и навсегда
- Аренда VDS на любой срок, с оплатой по дням
- Большое разнообразие конфигураций
- Дата-центры в ЕС и России
Здесь расскажу как добавить выбор дополнительного статуса (стикера) для товара в админке (в списке и в карточке) и вывести этот статус на сайт. Понадобится добавить одно поле в базу данных (БД), внести правки в файлы. Способ, который здесь описан, вероятно самый легкий с точки зрения нагрузки, но всего возможно не более 9 вариантов стикеров (в большинстве случаев их и столько не нужно).
Для начала в админке сделаю вывод в форму и список товаров, с возможностью сортировки, выведу на сайт. Затем сделаю управление не только через форму товара, но и через checkbox-ы в списке товаров.
Статусы (стикеры) которые буду добавлять:
Позже сможете свой список сделать, не сложно.
Первое что нужно сделать - добавить поле в БД. Начинаем с этого, т.к. если поля не будет к моменту обращения к нему, будет ошибка. Поле нужно только одно, вариантов статуса может быть сколько угодно, отличаться будут цифрой. Соответственно, добавляем в таблицу oc_product (вместо oc_ может быть любой другой префикс) следующее поле:
Поле будет такое:
Поле добавлено, в БД больше ничего не нужно, идем дальше. Теперь выводим поле в админке + предусматриваем, что будет сортировка и фильтрация по этому полю (правки model - controller - view). Ничего сложного, но долго и скучно (интереснее будет позже), можно копировать существуюшие части кода и менять на свое. Начнем.
Открываем admin/model/catalog/product.php. Здесь ищем по "status", почти везде где находим, добавляем аналогично "sticker":
Находим (в двух местах)
, status = '" . (int)$data['status'] . "'
Меняем (добавляем):
, status = '" . (int)$data['status'] . "', sticker = '" . (int)implode('', $data['sticker']) . "'
Здесь поясню. Из формы статусы приходят в виде массива, а в базу нужно записать число, соответственно преобразуем и записываем. Затем, при выводе, нужно будет это число "расчленить" на цифры и преобразовать в массив.
Идем дальше и находим (так же 2 раза):
if (isset($data['filter_status']) && !is_null($data['filter_status'])) {
$sql .= " AND p.status = '" . (int)$data['filter_status'] . "'";
}
Ниже добавляем (здесь есть небольшое отличие):
if (isset($data['filter_sticker']) && !is_null($data['filter_sticker'])) {
$sql .= " AND p.sticker LIKE '%" . (int)$data['filter_sticker'] . "%'";
}
Это нужно для сортировки по стикеру. Т.к. в поле несколько цифр, добавлен "%"
Далее находим:
$sort_data = array(
'pd.name',
'p.model',
'p.price',
'p.quantity',
'p.status',
'p.sort_order'
);
И внутрь добавляем (для сортировки, хотя польза от нее в данном случае сомнительна):
'p.sticker',
Здесь пока все. Переходим в контроллер и действуем по тому же принципу.
Файл admin/controller/catalog/product.php. Находим (8 совпадений):
if (isset($this->request->get['filter_status'])) {
$url .= '&filter_status=' . $this->request->get['filter_status'];
}
Ниже добавляем:
if (isset($this->request->get['filter_sticker'])) {
$url .= '&filter_sticker=' . $this->request->get['filter_sticker'];
}
Находим:
if (isset($this->request->get['filter_status'])) {
$filter_status = $this->request->get['filter_status'];
} else {
$filter_status = null;
}
Ниже добавляем:
if (isset($this->request->get['filter_sticker'])) {
$filter_sticker = $this->request->get['filter_sticker'];
} else {
$filter_sticker = null;
}
Находим в $filter_data :
'filter_status' => $filter_status,
И после добавляем:
'filter_sticker' => $filter_sticker,
В массив $data['products'][] добавляем (строка 390-какаято, это вывод отдельного товара в таблицу):
'sticker' => str_split($result['sticker']),
Находим:
$data['sort_status'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&sort=p.status' . $url, true);
Ниже добавляем:
$data['sort_sticker'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&sort=p.sticker' . $url, true);
Находим:
$data['filter_status'] = $filter_status;
Ниже добавляем:
$data['filter_sticker'] = $filter_sticker;
Ранее были беспорядочные правки, в основном для списка и формы сразу (одни и те же замены), следующее выводит поле в форму. Находим:
if (isset($this->request->post['status'])) {
$data['status'] = $this->request->post['status'];
} elseif (!empty($product_info)) {
$data['status'] = $product_info['status'];
} else {
$data['status'] = true;
}
Ниже добавляем:
if (isset($this->request->post['sticker'])) {
$data['sticker'] = $this->request->post['sticker'];
} elseif (!empty($product_info)) {
$data['sticker'] = str_split($product_info['sticker']);//число в массив
} else {
$data['sticker'] = array();
}
Состоит из двух файлов шаблонов, один отвечает за форму, другой за список. Начнем с формы.
admin/view/template/catalog/product_form.tpl
Находим:
<div class="form-group">
<label class="col-sm-2 control-label" for="input-status"><?php echo $entry_status; ?></label>
<div class="col-sm-10">
<select name="status" id="input-status" class="form-control">
<?php if ($status) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select>
</div>
</div>
Ниже добавляем:
<div class="form-group">
<label class="col-sm-2 control-label" for="input-sticker">Стикер</label>
<div class="col-sm-10 checkbox">
<input type="hidden" name="sticker[]" value="" checked />
<label><input type="checkbox" name="sticker[]" value="1" <?php if (in_array(1,$sticker)) { echo 'checked'; } ?> /> Новый</label>,
<label><input type="checkbox" name="sticker[]" value="2" <?php if (in_array(2,$sticker)) { echo 'checked'; } ?> /> Популярный</label>,
<label><input type="checkbox" name="sticker[]" value="3" <?php if (in_array(3,$sticker)) { echo 'checked'; } ?> /> Рекомендуем</label>
</div>
</div>
Здесь уже можно зайти в форму товара и проверить. Теперь список.
admin/view/template/catalog/product_list.tpl
Находим:
<div class="form-group">
<label class="control-label" for="input-model"><?php echo $entry_model; ?></label>
<input type="text" name="filter_model" value="<?php echo $filter_model; ?>" placeholder="<?php echo $entry_model; ?>" id="input-model" class="form-control" />
</div>
Добавляем:
<div class="form-group">
<label class="control-label" for="input-sticker">Стикер</label>
<select name="filter_sticker" id="input-sticker" class="form-control">
<option value="*"></option>
<option value="1" <?php if ($filter_sticker == '0') { echo 'selected="selected"'; } ?>>Нет</option>
<option value="1" <?php if ($filter_sticker == '1') { echo 'selected="selected"'; } ?>>Новый</option>
<option value="2" <?php if ($filter_sticker == '2') { echo 'selected="selected"'; } ?>>Популярный</option>
<option value="3" <?php if ($filter_sticker == '3') { echo 'selected="selected"'; } ?>>Рекомендуем</option>
</select>
</div>
Находим:
<td class="text-left"><?php if ($sort == 'p.status') { ?>
<a href="<?php echo $sort_status; ?>" class="<?php echo strtolower($order); ?>"><?php echo $column_status; ?></a>
<?php } else { ?>
<a href="<?php echo $sort_status; ?>"><?php echo $column_status; ?></a>
<?php } ?></td>
Добавляем:
<td class="text-left"><?php if ($sort == 'p.sticker') { ?>
<a href="<?php echo $sort_sticker; ?>" class="<?php echo strtolower($order); ?>">Стикер</a>
<?php } else { ?>
<a href="<?php echo $sort_sticker; ?>">Стикер</a>
<?php } ?></td>
Находим:
<td class="text-left"><?php echo $product['status']; ?></td>
Добавляем после:
<td class="text-left">
<?php $i=0; foreach ($product['sticker'] as $sticker) { $i++; ?>
<?php if ($i > 1) { echo '<br />'; } ?>
<?php if ($sticker == 1) { ?>Новый
<?php } else if ($sticker == 2) { ?>Популярный
<?php } else if ($sticker == 3) { ?>Рекомендуем<?php } ?>
<?php } ?>
</td>
Находим (ниже, в скриптах):
var filter_status = $('select[name=\'filter_status\']').val();
if (filter_status != '*') {
url += '&filter_status=' + encodeURIComponent(filter_status);
}
Добавляем:
var filter_sticker = $('select[name=\'filter_sticker\']').val();
if (filter_sticker != '*') {
url += '&filter_sticker=' + encodeURIComponent(filter_sticker);
}
На этом в админке добавлено, далее вывод на сайт
Здесь изменений меньше, что касается количества кода, поэтому не буду разбивать на отдельные шаги, все в одном, по файлам.
1. Catalog. Model. - catalog/model/catalog/product.php
В самом начале, где выводятся все поля товара, добавим sticker (здесь покажу только часть кода, нет смысла копировать все):
'minimum' => $query->row['minimum'],
'sort_order' => $query->row['sort_order'],
'status' => $query->row['status'],
'date_added' => $query->row['date_added'],
Здесь, например после status:
'sticker' => $query->row['sticker'] ? str_split($query->row['sticker']) : array(),
Здесь добавил проверку, что бы исключить "0" и сразу преобразовал в массив. И идем дальше, к контроллеру
2. Catalog. Controller. Здесь будет два примера - для контроллера отдельного товара и для контроллеров со списком товаров, вторых много, но все аналогично.
2.1. Отдельный товар. catalog/controller/product/product.php
После:
$data['model'] = $product_info['model'];
Добавим (всего одна строка, остальное в шаблоне):
$data['sticker'] = $product_info['sticker'];
2.2. Список товаров. На примере категории, аналогично в модулях, рекомендуемые в контроллере товара, поиск и т.д. catalog/controller/product/category.php
Здесь находим массив:
$data['products'][] = array(
Внутри этого массива добавим (например, после 'rating' => $result['rating'],):
'sticker' => $result['sticker'],
Далее вывод в шаблон, опять же, для двух вариантов
3. Catalog. View.
3.1. Отдельный товар. catalog/view/theme/default/template/product/product.tpl
В любом удобном месте:
<?php if ($sticker) { ?><div class="stickers">
<?php $name = 'NONAME'; foreach ($sticker as $item) { if ($item == 1) { $name = 'Новый'; } else if ($item == 2) { $name = 'Популярный'; } else if ($item == 3) { $name = 'Рекомендуем'; } ?>
<span class="sticker sticker-<?php echo $item; ?>"><?php echo $name; ?></span>
<?php } ?>
</div><?php } ?>
$name = 'NONAME' - добавлено на всякий случай. Если вдруг добавили новый вариант стикера и не везде прописали.
3.2. Шаблон списка товаров. catalog/view/theme/default/template/product/category.tpl
Где то после:
<?php foreach ($products as $product) { ?>
Вставляем:
<?php if ($product['sticker']) { ?><div class="stickers">
<?php $name = 'NONAME'; foreach ($product['sticker'] as $item) { if ($item == 1) { $name = 'Новый'; } else if ($item == 2) { $name = 'Популярный'; } else if ($item == 3) { $name = 'Рекомендуем'; } ?>
<span class="sticker sticker-<?php echo $item; ?>"><?php echo $name; ?></span>
<?php } ?>
</div><?php } ?>
Осталось скопировать последнее в шаблоны и контроллеры модулей для вывода товара, в поиск, товары производителя, акции и готово. Для большего удобства, что бы не заходить каждый раз в форму товара, лучше сделать назначение стикера из списка товаров в админке.
Снова понадобятся правки в модели, контроллере и шаблоне списка товаров в админке. Для начала - пропишем в шаблон выбор стикера, затем функцию в контроллер и еще одну в модель. Работаем с тем, что получилось после предыдущих изменений (которые кстати немного переписал для удобства).
1. admin/view/template/catalog/product_list.tpl - здесь находим в таблице вывод текущего стикера. Вот этот код:
<td class="text-left">
<?php $i=0; foreach ($product['sticker'] as $sticker) { $i++; ?>
<?php if ($i > 1) { echo '<br />'; } ?>
<?php if ($sticker == 1) { ?>Новый
<?php } else if ($sticker == 2) { ?>Популярный
<?php } else if ($sticker == 3) { ?>Рекомендуем<?php } ?>
<?php } ?>
</td>
Его нужно изменить. Будет список checkbox, как и в форме. Меняем:
<td id="change-sticker-<?php echo $product['product_id']; ?>" class="text-left form-group change-sticker-td" data-id="<?php echo $product['product_id']; ?>">
<input type="checkbox" name="change_sticker[]" value="1" <?php if (in_array(1,$product['sticker'])) { echo 'checked'; } ?> /> Новый<br />
<input type="checkbox" name="change_sticker[]" value="2" <?php if (in_array(2,$product['sticker'])) { echo 'checked'; } ?> /> Популярный<br />
<input type="checkbox" name="change_sticker[]" value="3" <?php if (in_array(3,$product['sticker'])) { echo 'checked'; } ?> /> Рекомендуем
</td>
Атрибут data-id у td нужен что бы узнать для какого товара делать изменение. Теперь напишем ajax запрос к функции в контроллере (которую чуть позже добавим). Перед <?php echo $footer; ?>:
<script>
$('.change-sticker-td input').on('click', function() {
var sticker = '';
$(this).parent().find('input[type=\'checkbox\']:checked').each(function(){
sticker = sticker+$(this).val();
});
var product_id = $(this).parent().data('id');
$.ajax({
url: 'index.php?route=catalog/product/changeSticker&token=<?php echo $token; ?>',
type: 'get',
data: {product_id:product_id,sticker:sticker},
dataType: 'html',
success: function(html) {
if(html != ''){
$('#change-sticker-'+product_id).addClass('ok');
} else {
$('#change-sticker-'+product_id).addClass('error');
}
}
});
});
</script>
Теперь нужно добавить функцию changeSticker в контроллер
2. admin/controller/catalog/product.php здесь находим:
public function autocomplete() {
Перед этой добавляем нашу функцию
public function changeSticker() {
$this->load->model('catalog/product');
$output='';
if(isset($this->request->get['product_id']) && isset($this->request->get['sticker'])){
$product_id = (int)$this->request->get['product_id'];
$sticker = (int)$this->request->get['sticker'];
$output = $this->model_catalog_product->changeSticker($product_id, $sticker);
}
$this->response->setOutput($output);
}
Из контроллера есть обращение к функции в модели. Значит теперь нужно прописать функцию и туда. последний шаг, на котором запишем новый стикер в БД
3. admin/model/catalog/product.php здесь находим:
public function getTotalProductsByLayoutId($layout_id) {
Перед найденной добавляем:
public function changeSticker($product_id, $sticker){
if ($this->user->hasPermission('modify', 'catalog/product')) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET sticker = '" . (int)$sticker . "' WHERE product_id = '" . (int)$product_id . "'");
return 'ok';
}
}
На этом все!!! Ocmod будет (уже жалею, что сразу не сделал), но позже
USDT TRC-20: TYTHLkNVjGu7PMGKbW8Vh54w1zkkVjFbWT
Классный мануал, спасибо!
А случайно нету у вас образца вывода под twig? Никак не соображу, как там прицепить
Вопрос, а если надо прикрепить к одному товару не один стикер, а все три, то как сделать?
Обычно в таких случаях делают несколько полей, вполне можно так и сделать. Здесь добавлено одно поле, по тому же принципу еще два добавить, только в каждом вместо списка стикеров — да/нет (1/0).
Еще как вариант (мне больше нравится, т.к. меньше полей в базе, да и кода поменьше), к текущим вариантам добавить "+":
1 — Новый
2 — Популярный
3 — Рекомендуем
4 — Новый+популярный
5 — новый+рекомендуем
6 — популярный+рекомендуем
___
только в шаблоне нужно будет сделать проверку, если <4 выводить 1 span, если больше, то 2. Можно с одним классом, а в CSS обращаться к .sticker-3 и .sticker-3+span (например)
Можно сделать просто чекбоксами?
Вообще то можно. Даже без увеличения количества полей, запросов… мысль хорошая, только мне придется много переписать (или даже отдельно написать) :(
Ждать? )
Да, думаю есть смысл, переделаю (тот вариант лучше). Опять же, ближе к ночи
напишите тогда тут ) Буду мониторить фидбэк )
Переписал. Пробуйте.
Не выводит стикеры на сайте, пишет ошибку:
yadi.sk/d/hV3ITF1kIQvLMA
А в списке товаров такая:
Ищите ошибки. Что то где то не добавили. или не туда. Не видя файлов (с изменениями) ничем не помогу. Можете прислать на vl@onenv.ru, посмотрю
ответил на почту
Благодарю еще раз за модуль
поощрил )
Спасибо!