Как написать свой модуль в OpenCart? Часть 2

Работа сис. админа
3 мин. на чтение

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

В OpenCart простой и понятный роутинг для всех элементов MVC(L). Чтобы понять где искать файл Представления, достаточно взглянуть на его упоминание в коде, например $this->load->controller('extensions/module1'); означает, что нужно искать файл в папке controller/extensions/module1.php.

Начнем создавать Представление, взяв за основу Представление модуля Google Analytics. Первым делом подключим Представления шапки и левой колонки нашей админ. панели:

<?php echo $header; ?><?php echo $column_left; ?>

Теперь допишем остальную часть Представления.

<?php echo $header; ?><?php echo $column_left; ?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-yandex-metrica" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
<?php if ($error_warning) { ?>
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-pencil"></i> <?php echo $text_edit; ?></h3>
</div>
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-yandex-metrica" class="form-horizontal">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> <?php echo $text_signup; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-code"><?php echo $entry_code; ?></label>
<div class="col-sm-10">
<textarea name="yandex_metrica_code" rows="5" placeholder="<?php echo $entry_code; ?>" id="input-code" class="form-control"><?php echo $yandex_metrica_code; ?></textarea>
<?php if ($error_code) { ?>
<div class="text-danger"><?php echo $error_code; ?></div>
<?php } ?>
</div>
</div>
<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="yandex_metrica_status" id="input-status" class="form-control">
<?php if ($yandex_metrica_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>
</form>
</div>
</div>
</div>
</div>
<?php echo $footer; ?>

Теперь админ часть нашего модуля готова, давайте посмотрим, что у нас получилось:

Включим модуль и запишем какой-нибудь код в поле, например <!--- CODE --!>, чтобы проверить что все корректно сохранилось в БД. Сохраняем и идем в базу данных, я сделаю это с помощью phpMyAdmin:

Как видим, наш код счетчика и статус корректно сохраняются в БД. Теперь можно перейти к фронт части модуля. Начнем по традиции с Контроллера, он крайне прост: по запросу к нему он просто берет из БД код счетчика, прогоняя его через функцию замены ISO символов на обычный HTML

<?php
class ControllerExtensionAnalyticsYandexMetrica extends Controller {
 public function index() {
 return html_entity_decode($this->config->get('yandex_metrica_code'), ENT_QUOTES, 'UTF-8');
 }
}

На самом деле кодинг закончен, осталось только понять как новый OpenCart 2.3 подключает модули типа Аналитики и делает это массово. Для этого обратимся к Контроллеру шапки сайта catalog/controller/common/header.php

За получение кодов счетчиков и статусов отвечает этот участок кода:

// Analytics
$this->load->model('extension/extension');

$data['analytics'] = array();

$analytics = $this->model_extension_extension->getExtensions('analytics');

foreach ($analytics as $analytic) {
if ($this->config->get($analytic['code'] . '_status')) {
$data['analytics'][] = $this->load->controller('extension/analytics/' . $analytic['code'], $this->config->get($analytic['code'] . '_status'));
}
}

Подключаем в Контроллер Модель для работы с модулями, создаем массив, в который будем складывать коды счетчика и статусы.

Для Моделей в OpenCart роутинг файлов немного отличается, в качестве разделителя используется символ «_» (нижее подчеркивание). Соответственно model_extension_extension будет эквивалентно файлу /catalog/model/extension/extension.php

Наша строка кода $analytics = $this->model_extension_extension->getExtensions('analytics'); положит все поля из таблицы БД extension, где тип дополнения analytics.

Завершающим аккордом будет цикл foreach, который разложит массив в отдельные переменные, проверит их (условие, чтобы значение статуса кода счетчика было 1, т.е. включено), далее пакуем уже только включенные коды счетчика в массив $data['analytics'][] и собственно, готовы передавать это в Представление, где оно выводится так же в цикле:

<?php foreach ($analytics as $analytic) { ?>
<?php echo $analytic; ?>
<?php } ?>

Все, проверяем есть ли наш код счетчика в исходном коде сайта:

Все, код есть на сайте, модуль написан корректнои работает.

P.S. Коллеги разработчики, обращаю ваше внимание, что целью этих статей было знакомство с разработкой модулей OpenCart и она не может претендовать на звание самой лучше статьи в этом направлении. Если вы нашли неточности или ошибки, пожалуйста сообщите мне об этом в комментариях или через форму обратной связи. Всем спасибо за внимание.

Игорь Чишкала

Директор по технологиям в SoftForge.
Люблю ИТ, пишу технические статьи в этом блоге или для сайта фриланс-биржи Upwork. Кодю на PHP с использованием фреймворков Laravel или Symfony.

Оцените автора
Авторский блог Игоря Чишкалы
Добавить комментарий для Игорь Чишкала Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

  1. Николай

    Добрый день, у вас в кусках кода попадается опечатка «yandex_metrica» что приводит к ошибкам. Также попробовал применить ваш подход на OpenCart 3 — не все так гладко работает, некоторые места отличаются, особенно та часть, которая в 3-й версии создает представления в формате twig. А так за статью большое спасибо!

    Ответить
    1. Игорь Чишкала автор

      Здравствуйте! Спасибо, проверю опечатки, писал в попыхах.
      Для OC3 этот метод не сработает в плане tpl. Там же twig. Пробуйте по аналогии с Google Analytics. Будут вопросы — пишите, постараюсь помочь.

      Ответить
  2. Artem

    Подскажите, хочу написать модуль, который будет менеджментить баннеры и блоки на главной. Какой модуль взять за основу? Не нашел ничего релевантного

    Ответить
    1. Ihor Chyshkala

      Artem, так собственно такой модуль есть. Если я корректно понял Вас. Он называется Схемы. Можно найти обычно, в Дизайн->Схемы. С версии 2.x там даже видно в Схемах, что активно. Какая версия OpenCart?

      P.S. Конечно, можно переписать свой контроллер, но есть ощущение, что это будет «мартышкин труд». Или у Вас академический интерес? :)

      Ответить
  3. Валерия

    Большое спасибо за статью!
    В Opencart 3.0.2 значения полей code и key таблицы setting должны быть в форматах
    тип_расширения_название_расширения (analytics_yandex_metrica) и
    тип_расширения_название_расширения_настройка (analytics_yandex_metrica_code, analytics_yandex_metrica_status) соответственно.

    Ответить