Доработка OpenCart: эргономика интерфейса и функциональная логика
В данной статье будут периодически появляться небольшие решения в плане улучшения эргономики интерфейса и функциональной логики OpenCart. Базовой версией для улучшения ПО магазина выбрана версия 1.5.4.
Предисловие
Не стоит гнаться за обновлениями успешного продукта, т.к. рано или поздно такой продукт станет неповоротливым и тяжёлым во всех смыслах. Помню, как начинал работать с ПО Bitrix, довольно быстрым и функциональным веб-приложением, сейчас же это программное обеспечение сильно нагружает не только сервер, но и людей. По тому же пути пошли и разработчики CS-Cart, а именно, стали добавлять много ненужных функций и модификаций, которые вроде и доставляют комфорт в работе (на мощных серверах), но на продажи магазинов существенно не влияют. Озвученные выше продукты коммерческие и они вынуждены наращивать избыточную функциональность, чтобы к ним не был потерян интерес.
OpenCart ПО открытое и свободное, в этом его основное преимущество, однако с каждым релизом работать с магазином становится сложнее, прежде всего в плане затрат на ресурсы сервера. Можно продолжать обновлять ПО с выходом каждого релиза, а можно остановиться на базовой версии и уже в ручном режиме вести необходимые доработки, т.к. OpenCart, как функциональный магазин, уже состоялся.
Решения
1. Скрытие продуктов для закрытых категорий.
Как известно, через панель администрирования можно отключать как продукты, так и категории (например на время внесения изменений). Если скрыта категория, то должны быть скрыты и продукты этой категории, однако по умолчанию придётся отключать все продукты отдельно, что не совсем удобно для большого количества товаров.
В файле модели ./catalog/model/catalog/product.php для функций getProduct, getProducts, getProductSpecials, getLatestProducts, getPopularProducts, getBestSellerProducts, getProductRelated, getTotalProducts, getTotalProductSpecials в тело условия sql-запроса WHERE после p.status = '1' везде необходимо добавить следующий код: AND (SELECT IFNULL(SUM(cat.status),1) FROM category cat INNER JOIN product_to_category p2cat ON (cat.category_id = p2cat.category_id) WHERE p2cat.product_id = p.product_id) > 0
Теперь ссылающиеся товары, товары производителей и товары в результатах поиска будут также скрыты, если скрыты их категории.
2. Увеличение "веса" ссылки для категории продуктов
Если включён режим SEO URL, то для продуктов в тело тега <head> добавляется каноническое имя страницы <link href="http://your.domain.com/seo_url" rel="canonical" />, котороё сообщает поисковому роботу приоритетный адрес этой страницы.
По аналогии такой же алгоритм должен выполняться и для категории продуктов, но видимо разработчики забыли его добавить.
В файл ./catalog/controller/product/category.php после строки $this->document->setKeywords($category_info['meta_keyword']); добавьте $this->document->addLink($this->url->link('product/category', 'path=' . $this->request->get['path']), 'canonical');
3. Сообщаем поисковым роботам о запрете индексирования несуществующих страниц сайта
Для начала необходимо привести в соостветствие заголовок об ошибке 404 (см. RFC 2616). В файле ./catalog/controller/error/not_found.php наидите строку $this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . '/1.1 404 Not Found'); и удалите из аргумента /1.1. Дело в том, что в переменной SERVER_PROTOCOL уже содержится (реальная) версия протокола.
Теперь стоит обратить внимание на запрет индексации подобных страниц, чтобы поисковый робот не отслеживал их. Для этого в файл ./system/library/document.php добавим следующие строки кода:
private $robots;
public function setRobots($robots) {
$this->robots = $robots;
}
public function getRobots() {
return $this->robots;
}
Далее в тело функции
index() файла
./catalog/controller/common/header.php добавим
$this->data['robots'] = $this->document->getRobots(); и соответственно внесём изменения для шаблона
./catalog/view/theme/default/template/common/header.tpl добавив следующий код:
<?php if ($robots) { ?>
<meta name="Robots" content="<?php echo $robots; ?>" />
<?php } ?>
Вернёмся в контроллер
not_found.php и после добавления заголовка страницы поместим строку
$this->document->setRobots('noindex');
Будет также логично провести вышеописанные изменения для контроллеров категории, продукта и производителя в той секции кода, где отрабатывается пустой результат, т.е. вывести сообщение об отсутствии категории, продукта или производителя с кодом 404 и запретом индексирования.
4. Сообщаем поисковым роботам о режиме обслуживания
В OpenCart есть удобная опция, позволяющая отключать магазин на время обслуживания. В этом режиме посетители видят соответствующее сообщение, а администратор сможет спокойно вносить изменения в список товаров или править код.
Однако для поисковых систем это не совсем хорошо, т.к. за время обслуживания сайт может быть переиндексирован с одной и той же страницей. Другими словами это негативно скажется на результатах поисковой выдачи. Необходимо сообщить роботам о технических работах на понятном для них языке.
Для этого в файл
/catalog/controller/common/maintenance.php до передачи страницы на рендеринг добавьте строку
$this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . ' 503 Service Temporarily Unavailable');.
Можно дополнить это решение, сообщить роботу спустя какой промежуток времени сайт станет доступным.
5. Выгрузка базы данных больших размеров из панели администрирования OpenCart
При работе с базой данных через пункт меню "Резервное копирование", браузер может неожиданно сбросить соединение. Одна из основных причин - нехватка памяти, выделенной скрипту. В журнале ошибок Apache могут быть сообщения вида
Fatal error: Allowed memory size exhausted, что подтвердит описанную выше проблему.
Одним из решений может быть её увеличение, но не на каждом хостинге это возможно, другим - резервирование базы данных по частям (по отдельным таблицам), однако это не совсем удобно. Есть и другой вариант, который был нами разработан, связан он с изменением алгоритма работы функции
backup.
6. Доработка менеджера файлов или окна управления изображениями
В OpenCart управление изображениями осуществляется через файл
~/admin/controller/common/filemanager.php при помощи мода
jsTree для библиотеки jQuery. Мод отличается от других ему подобных своей простотой и элегантностью, но каждый раз открывая менеджер файлов в панели управления OpenCart, приходится раскрывать всё дерево в поисках текущего каталога для сохраненного файла, а потом уже и поиска самого файла среди множества других. Это очень неудобно и отнимает большое количество времени при наличии сложной иерархической структуры файлового хранилища. Однако было найдено решение и для этой проблемы!
7. Обращаем внимание на список рекомендуемых товаров
На главной странице магазина при помощи модуля
Featured можно выводить список рекомендуемых товаров. Для постоянных посетителей этот список может быстро потерять актуальность, поскольку они могут к нему "привыкнуть". Хорошо бы данный список перемешивать каждый раз при открытии страницы. Поручить эту задачу стоит самому модулю (
~/catalog/controller/module/featured.php), добавив в код функцию
перемешивания ассоциативного массива.
8. Массовая рассылка сообщений покупателям OpenCart
В OpenCart есть сервис рассылки электронных писем покупателям и партнерам магазина (меню
Продажи > Почта). Довольно полезная утилита, всегда есть возможность сообщить о ключевых новостях непосредственно по E-mail. Однако при большом количестве зарегистрированных пользователей в системе, такая рассылка попадает под определение массовой, на которую могут быть наложены санкции со стороны провайдера. Речь идёт об ограничениях на количество рассылаемых писем в единицу времени на хостинге. Функционал этой утилиты был успешно доработан, теперь появилась возможность задавать очередь сообщений с определенным интервалом в интерактивном режиме (отображение информации о ходе рассылки в реальном времени).
9. Определение "красной" цены в OpenCart
По умолчанию в OpenCart если товар участвует в акции, то визуально его старая цена перечеркнута в красном цвете, а новая стоит рядом (в черном). Однако это в корне неверно, поскольку в науке о продажах сказано, что "красная" цена - это минимально возможная цена, которая удовлетворяет как покупателя, так и продавца. В файле стилей stylesheet.css для классов
.price-new и
.price-old цвета нужно поменять местами.
10. Не учитывается часовой пояс при формировании дат.
Это больше касается настроек сервера, нежели OpenCart. Суть проблемы в том, что в журнал ошибок OpenCart записываются записи с временем отличным от времени сервера. Тоже самое касается начала действия акций, срока существования корзины покупателя и т.д. Основная причина - это отсутствие временной зоны по умолчанию в файле php.ini. Исправить можно несколькими способами:
1) В файле php.ini найти секцию
и прописать действующую временную зону, например, [b]date.timezone = Europe/Moscow
2) В файле .htaccess через переменные окружения задать
SetEnv TZ Europe/Moscow
3) В начале индексных файлов OpenCart добавить строку
date_default_timezone_set(" Europe/Moscow");
11. Показ скрытых цен для авторизованных пользователей OpenCart.
Если в магазине скрыты цены для гостей, то при редактировании карточек товаров не всегда удобно проверять страницу товара под видом рядового посетителя. Приходится проходить авторизацию под тестовой учетной записью покупателя или отключать соответствующую опцию в настройках магазина. Чтобы об этом не думать, достаточно в файле ./index.php после строки $config->set('config_language', $languages[$code]['code']); добавить следующий код:
if (empty($session->data['user_id']) == false) { $config->set('config_customer_price', false); }
12. Показ того или иного модуля на всех возможных страницах сайта без задания этих страниц по отдельности.
Есть модули, которые необходимо показывать на любой из существующих страниц сайта. Чтобы это сделать, необходимо сначала определить все эти страницы в справочнике Схемы (Система -> Дизайн -> Схемы), а затем задать их в настройках конкретного модуля. В каком-то смысле это не совсем удобно, можно упустить какой-нибудь из разделов сайта, а в памяти процесса появится много настроек (актуально для большого количества типовых модулей).
Чтобы появилась возможность активировать тот или иной модуль на всех страницах магазина сразу, потребуется внести изменения в следующие файлы:
./catalog/controller/common/column_left.php
./catalog/controller/common/column_right.php
./catalog/controller/common/content_bottom.php
./catalog/controller/common/content_top.php
В этих файлах найдите запись
$module['layout_id'] == $layout_id и замените на
($module['layout_id'] == $layout_id || $module['layout_id'] == $this->config->get('config_layout_id')). Теперь если для модуля выбрать одну из схем по умолчанию, которая задаётся в настройках магазина, то он будет показан при открытии любой страницы сайта.