В данной статье процесс создания модуля для OpenCart:



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


ОПИСАНИЕ МОДУЛЯ

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

Установка:
- содержимое архива скопировать в корневую папку;
- ДОПОЛНЕНИЯ – Дополнения – Модули – выбрать из списка «Категории_KSL»;
- установить, открыть для редактирования;
- изменить статус на «Включено» и настроить согласно своим требованиям;
- сохранить изменения.

Добавление колонки на нужную страницу:
- Дизайн – Схемы – Главная (или нужная страница);
- выбрать левую или правую колонку;
- найти и выбрать в списке «Категории_KSL»;
- нажать кнопку «Добавить модуль»;
- сохранить изменения.

Можно включить/отключить кол-во товаров выводимое после названия категорий в скобках так же как и для стандартного модуля категорий, в:
- СИСТЕМА – Настройки – редактирование – Опции - Счётчик товаров в категории


ПРОЦЕСС СОЗДАНИЯ

В OpenCart версии 2.3 файлы модулей хранятся в папке extension\module.
Файлы данного модуля я решил назвать «categoryKsl». В OpenCart принято назвать файлы одного модуля одинаково, например categoryKsl.php для контроллера, модели, языкового файла и categoryKsl.tpl для файла-представления.

Админка.
Контроллер и другие файлы в каталоге admin создаются, если модуль должен включаться/выключаться в админке и тем более, если должен иметь какие-то настройки.

Обязательно создается контроллер. В нашем случае это
admin\controller\extension\module\categoryKsl.php
При разработке своего модуля, проще всего скопировать контроллер другого, стандартного модуля (желательно похожего по функционалу) и вносить свои изменения, чтобы ничего не забыть прописать. Для написания админ-части данного модуля, я использовал файлы стандартного модуля категорий и менял под свои нужды:
контроллер - admin\controller\extension\module\category.php
язык.файл - admin\language\ru-ru\extension\module\category.php
вид - admin\view\template\extension\module\category.tpl



В контроллере подключаются нужные модели, языковые файлы, виды. Данные файлы создаются так же в папке extension\module (модели, языкового файла или вида).

Название для класса контроллера и модели пишутся согласно пути по которому файл находится:
ControllerExtensionModuleCategoryKsl
тут название класса контроллера у меня CategoryKsl.



Опишу основные элементы контроллера.
В контроллере проверяется отправка формы:
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate())

Форма отправляется из вида, когда на странице модуля была нажата кнопка «Сохранить».
Далее вызывается метод editSetting() модели и данные сохраняются в таблицу oc_setting. Данная таблица используется для хранения настроек разных модулей.
$this->model_setting_setting->editSetting('categoryKsl', $this->request->post)
Первым элементом методу передается ключ – название модуля, которое проставляется в каждой строке таблицы с одной из настроек модуля.
Важный момент – элементы формы, которые будут переданы POST-запросом на сервер, должны иметь атрибут name начинающийся с данного ключа. В нашем случае, например:
<select name="categoryKsl_status" id="input-status" class="form-control">
иначе соответствующая проверка в методе пройдена не будет и данные не сохранятся. Вторым элементом методу передается массив параметров полученных из формы.

Я решил сделать кнопку «Применить» для применения новых настроек без закрытия страницы модуля, для этого я создал в форме отдельную кнопку, которая, при нажатии, дополнительно к форме отправляет параметр ksl_save. В результате, в контроллере, я проверяю была ли нажата эта кнопка и если да, то перенаправляю обратно на эту же страницу:
if (isset($post['ksl_save'])){
    $this->response->redirect($this->url->link('extension/module/categoryKsl', 'token=' . $this->session->data['token'], true));
} else {
    $this->response->redirect($this->url->link('extension/extension', 'token=' . $this->session->data['token'] . '&type=module', true));
}

Подобными блоками кода, я передаю в форму сохраненные ранее значения или значения по-умолчанию:
if (isset($this->request->post['categoryKsl_status'])) {
    $data['categoryKsl_status'] = $this->request->post['categoryKsl_status'];
} else {
    $data['categoryKsl_status'] = $this->config->get('categoryKsl_status');
}

Что еще я сделал, так это создал модель
admin\model\catalog\categoryKsl.php
и перенес в нее метод getCategories() из аналогичной модели в каталоге Catalog. Т.к. хотел, чтобы в админке модуля, категории выводились таким же образом как на обычной странице в frontend, что нужно для использования чекбоксов.
При возможности, всегда лучше использовать существующие модели и методы, а не писать свои.
Подключаем модель
$this->load->model('catalog/categoryKsl');

Получаем список родительских категорий:
$categories = $this->model_catalog_categoryKsl->getCategories(0);
Строкой
$this->document->addScript('view/javascript/categoryKSL/ksl.js');
я подключил js файл, в котором сделал, чтобы при нажатии соответствующих кнопок, для всех категорий проставлялась отметка «включено» или «выключено».

Далее в цикле так же для каждой категории проверяем наличие дочерних категорий, получаем нужные данные и сохраняем в массив $data. Который, в конце метода, передается в файл-представление:
$this->response->setOutput($this->load->view('extension/module/categoryKsl', $data));

Сам файл представления admin\view\template\extension\module\categoryKsl.tpl
так же, делаем на основе файла похожего модуля. Тогда там уже будет прописан код подключения шапки, левой колонки с меню и тд.:
<?php echo $header; ?>
<?php echo $column_left; ?>

Далее обычная форма, только не забываем проставлять атрибут name у элементов согласно ключа, как я писал выше.
Так же создаем языковой файл(ы), который загружается в контроллере, а данные сохраняются в общий массив $data и передаются в вид.


Catalog.
Чтобы вывести файл-представление нашего модуля, нужно выбрать на какой странице и в какой части шаблона он будет выводиться. Что делается в админ-панели: Дизайн – Схемы. Например выводим на главной странице в левой колонке.

Создаем контроллер (файл catalog\controller\extension\module\categoryKsl.php), который будет подключаться в выбранном месте указанного шаблона.

Вначале разбираем текущий URL на предмет указания в нем id категории. Сделаем, чтобы в файле-представлении текущая категория выводилась в рамке. Конечно это не будет работать для главной страницы и других, а только для страницы определенной категории.

Далее как обычно, загружаем нужные модели и получаем данные, сохраняя в общем массиве $data для передачи в вид. Например получаем массив категорий:
$this->load->model('catalog/category');
$categories = $this->model_catalog_category->getCategories(0);

Далее в цикле, как и для админки, для каждой категории проверяем наличие дочерних категорий, получаем нужные данные и сохраняем в массив $data.

При выводе нашего блока, я решил использовать стили стандартного модуля категорий и добавил несколько своих в отдельном файле, который подключаем аналогично файлу js из админки:
$this->document->addStyle('catalog/view/theme/default/stylesheet/categoryKSL.css');

По аргументу метода addStyle() видно, что стили должны находиться в файле catalog\view\theme\default\stylesheet\categoryKSL.css

Строкой
return $this->load->view('extension/module/categoryKsl', $data);
подключаем файл-представление catalog\view\theme\default\template\extension\module\categoryKsl.tpl
он намного проще, чем для админ-панели, т.к. не содержит формы, только цикл вывода категорий с подкатегориями со вставками ссылок и картинок. Форму же придают CSS стили, соответственно изменяя стили, можно настроить внешний вид.

Модуль готов. Если понять принцип по которому он создавался и как связаны между собой контроллер/модель/вид в OpenCart, то поймете, что создание модулей дело не особо сложное. Правда в данном модуле не пришлось использовать модификатор или события, но и там вполне можно разобраться, тем более, что мной написаны соответствующие статьи для данного сайта.