Admin controller catalog product php

Opencart, OcStore: Умный фильтр и поиск

Запуская интернет магазин, столкнулся с проблемой при которой фильтр товаров не отрабатывал на подстроку, которая начинается не с первого символа. Исправил в своей версии, получилось удобно. Решил запилить про это пост-заметку, чтобы в будущем использовать и в других местах..

Итак, начнем с описания проблемы:

  1. Заходим в админку и создаем товар, с названием Test12345
  2. Пробуем вбить в фильтр в поле имени: Test — видим наш товар
  3. Пробуем вбить в фильтр в поле имени: t123 — не видим наш товар

Смотрим исходник контроллера: /admin/controller/catalog/product.php

там видим, что запрос передается в модель: /admin/model/catalog/product.php

открываем её и видим что запрос формируется таким образом:

Как видим фильтр позволяет опускать только последнюю часть. Сделанно так неспроста и связанно это с тем как mysql обрабатывает запросы, а точнее с производительностью. Вдаваться в подробности не буду, пост не про это. Кому интересно читайте в справке mysql о том как работает LIKE оператор.

Что же делать, ведь всё же хочется иногда искать по выражению %Condition% — все просто, добавим условный оператор в запрос, при наличии которого будет искать по %Condition%, а во всех остальных случаях, по оригинальному Condition%. В качестве такого оператора, я выбрал знак восклицания. Меняем код так :

Источник

OpenCart: как добавить фильтр по артикулу в админке

В стандартном фильтре в админке нельзя «фильтровать» товары по артикулу. Когда у вас тысячи товаров, такой фильтр в разы ускоряет поиск конкретного товара.

Что делать

protected function getList() 
if (isset($this->request->get['filter_sku'])) < $filter_sku = $this->request->get['filter_sku']; > else < $filter_sku = ''; >$data['filter_sku'] = $filter_sku;
if (isset($this->request->get['filter_sku'])) < $url .= '&filter_sku=' . $this->request->get['filter_sku']; >
'filter_sku' => isset($filter_sku) ? $filter_sku : '',
  1. Сохраняем, обновляеем кэш.
  1. Открываем сайт/admin/model/catalog/product.php
  1. Находим код (~361 строка):
if (!empty($data['filter_name'])) < $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'"; >
if (isset($this->request->get['filter_sku']) && !empty($data['filter_sku'])) < $sql .= " AND p.sku = '" . $this->db->escape($data['filter_sku']) . "'"; >
  1. Сохраняем, обновляем кэш.
  1. Открываем сайт/admin/view/template/catalog/product_list.twig
  1. Находим код (~68 строка):
var filter_status = $('select[name=\'filter_status\']').val();
var filter_sku = $('input[name=\'filter_sku\']').val(); if (filter_sku)

Источник

Стикеры для товаров: новинка, рекомендуемый, популярный

Стикеры для товаров: новинка, рекомендуемый, популярный

Здесь расскажу как добавить выбор дополнительного статуса (стикера) для товара в админке (в списке и в карточке) и вывести этот статус на сайт. Понадобится добавить одно поле в базу данных (БД), внести правки в файлы. Способ, который здесь описан, вероятно самый легкий с точки зрения нагрузки, но всего возможно не более 9 вариантов стикеров (в большинстве случаев их и столько не нужно).

Для начала в админке сделаю вывод в форму и список товаров, с возможностью сортировки, выведу на сайт. Затем сделаю управление не только через форму товара, но и через checkbox-ы в списке товаров.

Статусы (стикеры) которые буду добавлять:

Позже сможете свой список сделать, не сложно.

Шаг 1. БД

Первое что нужно сделать - добавить поле в БД. Начинаем с этого, т.к. если поля не будет к моменту обращения к нему, будет ошибка. Поле нужно только одно, вариантов статуса может быть сколько угодно, отличаться будут цифрой. Соответственно, добавляем в таблицу oc_product (вместо oc_ может быть любой другой префикс) следующее поле:

Добавляем поле в БД

  • Имя: sticker
  • Тип: INT
  • Длина: 11
  • По умолчанию: 0 (как определено) - для всех "обычных" товаров

Добавляем поле в БД - параметры

Поле добавлено, в БД больше ничего не нужно, идем дальше. Теперь выводим поле в админке + предусматриваем, что будет сортировка и фильтрация по этому полю (правки model - controller - view). Ничего сложного, но долго и скучно (интереснее будет позже), можно копировать существуюшие части кода и менять на свое. Начнем.

Шаг 2. Admin. Model.

admin/model/catalog/product.php

Здесь ищем по "status", почти везде где находим, добавляем аналогично "sticker":

, status = '" . (int)$data['status'] . "', sticker = '" . (int)implode('', $data['sticker']) . "'

Здесь поясню. Из формы статусы приходят в виде массива, а в базу нужно записать число, соответственно преобразуем и записываем. Затем, при выводе, нужно будет это число "расчленить" на цифры и преобразовать в массив.
Идем дальше и находим (так же 2 раза):

if (isset($data['filter_status']) && !is_null($data['filter_status']))

Ниже добавляем (здесь есть небольшое отличие):

if (isset($data['filter_sticker']) && !is_null($data['filter_sticker']))

Это нужно для сортировки по стикеру. Т.к. в поле несколько цифр, добавлен "%"

$sort_data = array( 'pd.name', 'p.model', 'p.price', 'p.quantity', 'p.status', 'p.sort_order' );

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

Здесь пока все. Переходим в контроллер и действуем по тому же принципу.

Шаг 3. Admin. Controller.

admin/controller/catalog/product.php

Находим (таких будет 8, не 4):

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
if (isset($this->request->get['filter_sticker'])) < $filter_sticker = $this->request->get['filter_sticker']; > else
'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
if (isset($this->request->post['sticker'])) < $data['sticker'] = $this->request->post['sticker']; > elseif (!empty($product_info)) < $data['sticker'] = str_split($product_info['sticker']);//число в массив >else

Шаг 4. Admin. View.

Состоит из двух файлов шаблонов, один отвечает за форму, другой за список. Начнем с формы.

admin/view/template/catalog/product_form.tpl

  
, ,

Здесь уже можно зайти в форму товара и проверить. Теперь список.

admin/view/template/catalog/product_list.tpl

  
   1) < echo '
'; > ?> Новый else if ($sticker == 2) < ?>Популярный else if ($sticker == 3) < ?>Рекомендуем ?> ?>
 var filter_status = $('select[name=\'filter_status\']').val(); if (filter_status != '*')
 var filter_sticker = $('select[name=\'filter_sticker\']').val(); if (filter_sticker != '*')

На этом в админке добавлено, далее вывод на сайт

Шаг 5. Frontend.

Здесь изменений меньше, что касается количества кода, поэтому не буду разбивать на отдельные шаги, все в одном, по файлам.

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

Внутри этого массива добавим (например, после 'rating' => $result['rating'],):

Далее вывод в шаблон, опять же, для двух вариантов

3.1. Отдельный товар. catalog/view/theme/default/template/product/product.tpl

 
else if ($item == 2) < $name = 'Популярный'; >else if ($item == 3) < $name = 'Рекомендуем'; >?> ?>
?>

$name = 'NONAME' - добавлено на всякий случай. Если вдруг добавили новый вариант стикера и не везде прописали.

3.2. Шаблон списка товаров. catalog/view/theme/default/template/product/category.tpl

 
else if ($item == 2) < $name = 'Популярный'; >else if ($item == 3) < $name = 'Рекомендуем'; >?> ?>
?>

Осталось скопировать последнее в шаблоны и контроллеры модулей для вывода товара, в поиск, товары производителя, акции и готово. Для большего удобства, что бы не заходить каждый раз в форму товара, лучше сделать назначение стикера из списка товаров в админке.

Шаг 6. Admin. Смена стикера в списке товаров (Ajax).

Снова понадобятся правки в модели, контроллере и шаблоне списка товаров в админке. Для начала - пропишем в шаблон выбор стикера, затем функцию в контроллер и еще одну в модель. Работаем с тем, что получилось после предыдущих изменений (которые кстати немного переписал для удобства).

1. admin/view/template/catalog/product_list.tpl - здесь находим в таблице вывод текущего стикера. Вот этот код:

    1) < echo '
'; > ?> Новый else if ($sticker == 2) < ?>Популярный else if ($sticker == 3) < ?>Рекомендуем ?> ?>

Его нужно изменить. Будет список checkbox, как и в форме. Меняем:

 ?> /> Новый 
?> /> Популярный
?> /> Рекомендуем

Атрибут data-id у td нужен что бы узнать для какого товара делать изменение. Теперь напишем ajax запрос к функции в контроллере (которую чуть позже добавим). Перед :

  

Теперь нужно добавить функцию 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 будет (уже жалею, что сразу не сделал), но позже

Источник

Читайте также:  JSON to HTML Table | Javacodepoint
Оцените статью