Экспресс-обзор Xiaomi Mi TDS и TDS-3

TDS метр (тестер, солемер) — устройство для измерения минерализации воды, т.е содержания в ней твёрдых веществ (солей). Сама аббревиатура означает Total Dissolved Solids (общее количество растворённых частиц).

В обзоре я сравню два китайских прибора: один от известного бренда Xiaomi за 7$, второй безбрендовый TDS-3 за 3$, но тоже весьма популярный на Aliexpress.

Подробнее

Экспресс-обзор KSD9700

KSD9700
Создание сайта на CMS WordPress: обучение и хостинг
KSD9700 — биметаллический температурный переключатель, многие называют термостатом, термореле, термопредохранителем, термодатчиком, термоконтактом и др. Принцип работы элементарный: внутри корпуса два контакта, которые изначально замкнуты/разомкнуты (зависит от типа). При нагреве биметаллическая пластина изгибается и в определённый момент размыкает или замыкает контакты, при остывании возвращаются в исходное состояние.

Подробнее

Обзор роутера Tenda N630 v2

Представляю вашему вниманию обзор-тестирование одного из самых бюджетных роутеров Tenda N630 v2: цена на момент покупки всего 11$ (690 рублей).

Заказывал на Aliexpress, т.к в Россию эта модель официально не поставляется. Конечно же, я понимал, что за такие деньги ничего хорошего быть не может, но и особых требований не было, лишь бы стабильно раздавал Интернет по Wi-Fi и LAN.

Подробнее

Добавление нового столбца в таблицу товаров админки OpenCart 2

Способ в статье рабочий, но редактировать исходные файлы в OcStore/OpenCart считается «костылем», гораздо правильней написать модификацию (OCmod) и установить стандартными средствами движка, возможно такие модификации уже существуют, поищите, в любом случае не забывайте делать backup!
Задача: в админ-панели OpenCart 2 (тестировалось на версии 2.0.3.1, но должно работать и в более новых 2.x, а также в ocStore 2.x) на странице Каталог->Товары добавить новый столбец в таблицу товаров. Пускай это будет уже предусмотренное в движке поле UPC.

1) Файл product_list.tpl (/admin/view/template/catalog/product_list.tpl)

В product_list.tpl формируется таблица со списком товаров. Начинаем с заголовка таблицы (thead). Пусть новый столбец будет выводиться после столбца "Статус", находим этот фрагмент кода:

<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.upc') { ?>
<a href="<?php echo $sort_upc; ?>" class="<?php echo strtolower($order); ?>"><?php echo 'UPC'; ?></a>
<?php } else { ?>
<a href="<?php echo $sort_upc; ?>"><?php echo 'UPC'; ?></a>
<?php } ?></td>

То есть мы скопировали код вывода столбца "Статус" в шапке таблицы и вставили ниже, изменив p.upc вместо p.status, $sort_upc вместо $sort_status, а вместо "echo $column_status" написали 'echo UPC', иначе пришлось бы вносить изменения еще в языковой файл.

Теперь тело таблицы (tbody). Находим:

<td class="text-left"><?php echo $product['status']; ?></td>

Добавляем строку ниже:

<td class="text-left"><?php echo $product['upc']; ?></td>

Последнее мелкое изменение:

<td class="text-center" colspan="8"><?php echo $text_no_results; ?></td>

Изменяем colspan на 9, чтобы таблица не "ломалась", если товары не найдены.

Смотрим, что получилось:
Добавление столбца OpenCart

Столбец добавился, но внутри пока ничего не выводится. Если на сервере включено отображение предупреждений может быть так: "Notice: Undefined index: upc in [путь]/public_html/admin/view/template/catalog/product_list.tpl on line 255".

2) Файл product.php (/admin/controller/catalog/product.php)

Этот файл отвечает за вызов "model", обработку и подготовку полученных данных для вывода в "view".
Делаем поиск по sort_status, будет всего одна строчка. Дублируем и меняем на sort_upc, должно получиться так:

$data['sort_status'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&amp;amp;sort=p.status' . $url, 'SSL');
$data['sort_upc'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&amp;amp;sort=p.upc' . $url, 'SSL');

Затем находим массив $data['products'][] и после строки:

'status'     => ($result['status']) ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),

добавляем:

'upc'		=> $result['upc'],

3) Файл product.php (/admin/model/catalog/product.php)

В этом файле формируются запросы к базе данных, которые затем используются в "controller". Нужно внести только одну изменение: находим массив $sort_data и добавляем p.upc, получится так:

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

Все работает:
Добавление столбца OpenCart
Если после этих действий ничего не заработало:

  • попробуйте очистить кэш на странице "Расширения"-"Модификаторы" (если магазин уже функционирует советую перед этим сделать резервную копию файлов и БД)
  • возможно, вы допустили ошибки в коде, проверьте логи в админ-панели или в файле /system/logs/error.log

Добавление нового поля фильтра товаров в админке OcStore/OpenCart 2

Код рабочий, но редактировать исходные файлы в OcStore/OpenCart нехорошо, гораздо правильней создать модуль и установить его стандартными средствами движка.
В интернете пошаговых инструкций (для новичков) по этой теме я не нашел, решил поделиться информацией. Задача: в админ-панели OpenCart (в OcStore также должно работать) на странице Каталог->Товары добавить новый фильтр по какому-нибудь существующему полю. Для примера пусть будет поле UPC:
OpenCart добавление поля

1) Файл product.php (/admin/controller/catalog/product.php)

Тут придется добавлять изменения в более чем 10 разных местах. Приятный момент в том, что особо придумывать ничего не нужно, достаточно копировать готовые куски кода и менять имена.
Так как поле UPC хранится в базе данных с типом varchar, я выбрал для копирования существующий фильтр filter_model с таким же типом данных.
Пример первого скопированного куска кода (33 строка):

if (isset($this->request->get['filter_model'])) {
$url .= '&filter_model=' . urlencode(html_entity_decode($this->request->get['filter_model'], ENT_QUOTES, 'UTF-8'));
}
			
if (isset($this->request->get['filter_upc'])) {
$url .= '&filter_upc=' . urlencode(html_entity_decode($this->request->get['filter_upc'], ENT_QUOTES, 'UTF-8'));
}

Продолжая искать по коду "filter_model" я произвожу аналогичные действия: копирую, вставляю ниже и меняю имена. Исключение — в конце функция autocomplete, туда я не добавляю filter_upc.

2) Файл product.php (/admin/model/catalog/product.php)

В коде из каталога model происходит работа с базой данных. Ищу по filter_model, нахожу куски кода в функциях getProducts и getTotalProducts. В обоих дублирую и меняю имена:

if (!empty($data['filter_model'])) {
$sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_model']) . "%'";
}
		
if (isset($data['filter_upc']) && !is_null($data['filter_upc'])) {
$sql .= " AND p.upc LIKE '" . $this->db->escape($data['filter_upc']) . "%'";
}

3) Файл product_list.tpl (/admin/view/template/catalog/product_list.tpl)

Открываем и находим последний div с классом col-sm-4, внутри него выводится поле статуса товара:

<div class="col-sm-4">

<div class="form-group">
<label class="control-label" for="input-status"><?php echo $entry_status; ?></label>
<select name="filter_status" id="input-status" class="form-control">
<option value="*"></option>
<?php if ($filter_status) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<?php } ?>
<?php if (!$filter_status && !is_null($filter_status)) { ?>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } ?>
</select>
</div>

Добавляем сразу после этого:

<div class="form-group">
<label class="control-label" for="input-upc"><?php echo 'UPC'; ?></label>
<input type="text" name="filter_upc" value="<?php echo $filter_upc; ?>" placeholder="<?php echo 'UPC'; ?>" id="input-upc" class="form-control" />
</div>

То есть просто берем часть готового кода и меняем имена атрибутов и полей, например $entry_upc, $filter_upc.

В конце product_list.tpl есть javascript, который обрабатывает нажатие кнопки "Фильтр", а именно проверяет какие поля фильтра были заполнены, формирует URL и перенаправляет на него. Здесь тоже копируем кусок кода с filter_quantity, вставляем после него и меняем имена на filter_upc:

var filter_upc = $('input[name=\'filter_upc\']').val();
if (filter_upc) {
url += '&filter_upc=' + encodeURIComponent(filter_upc);
}

Готово! Проверяю работает ли фильтрация. При заполнении поля UPC и нажатии кнопки фильтра в URL-строки должно добавляться &filter_upc=[содержимое поля].

На всякий случай добавляю изменённые файлы, версия OpenCart 2.0.3.1: скачать (обязательно сделайте резервную копию, если надумаете скопировать сами файлы).