Страница настроек модуля
Почти у каждого модуля есть настройки: как минимум переключатель «включён» и какой-нибудь текст. Страница настроек — это контроллер панели в дополнении. Он показывает форму, а второй метод сохраняет значения моделью ядра setting/setting.
Файлы
extension/acme_hello/admin/
├── controller/module/acme_hello.php
├── language/en-gb/module/acme_hello.php
└── view/template/module/acme_hello.twigТексты
// extension/acme_hello/admin/language/en-gb/module/acme_hello.php
$_['heading_title'] = 'Acme Hello';
$_['text_success'] = 'Settings saved.';
$_['entry_text'] = 'Greeting text';
$_['entry_status'] = 'Status';
$_['error_permission'] = 'You do not have permission to modify this module.';Контроллер
// extension/acme_hello/admin/controller/module/acme_hello.php
public function index(): void
{
$this->load->language('extension/acme_hello/module/acme_hello');
$this->document->setTitle($this->language->get('heading_title'));
$token = 'user_token=' . $this->session->data['user_token'];
$data['save'] = $this->url->link('extension/acme_hello/module/acme_hello.save', $token);
$data['back'] = $this->url->link('marketplace/extension', $token . '&type=module');
$data['module_acme_hello_text'] = $this->config->get('module_acme_hello_text');
$data['module_acme_hello_status'] = $this->config->get('module_acme_hello_status');
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput($this->load->view('extension/acme_hello/module/acme_hello', $data));
}Пути к файлу перевода и шаблону начинаются с extension/acme_hello/. Текущие значения читаются из $this->config. В каждой ссылке панели есть user_token — о нём следующий урок.
Форма
{# extension/acme_hello/admin/view/template/module/acme_hello.twig #}
{{ header }}{{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="float-end">
<button type="submit" form="form-module" class="btn btn-primary">{{ button_save }}</button>
<a href="{{ back }}" class="btn btn-light">{{ button_back }}</a>
</div>
<h1>{{ heading_title }}</h1>
</div>
</div>
<div class="container-fluid">
<form id="form-module" action="{{ save }}" method="post" data-oc-toggle="ajax">
<div class="row mb-3">
<label for="input-text" class="col-sm-2 col-form-label">{{ entry_text }}</label>
<div class="col-sm-10">
<input type="text" name="module_acme_hello_text" value="{{ module_acme_hello_text }}" id="input-text" class="form-control">
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_status }}</label>
<div class="col-sm-10">
<div class="form-check form-switch form-switch-lg">
<input type="hidden" name="module_acme_hello_status" value="0">
<input type="checkbox" name="module_acme_hello_status" value="1" class="form-check-input"{% if module_acme_hello_status %} checked{% endif %}>
</div>
</div>
</div>
</form>
</div>
</div>
{{ footer }}Откройте Extensions → Extensions → Modules → Acme Hello → Edit — на странице текстовое поле и переключатель.
Сохранение
public function save(): void
{
$this->load->language('extension/acme_hello/module/acme_hello');
$this->load->model('setting/setting');
$this->model_setting_setting->editSetting('module_acme_hello', $this->request->post);
$json['success'] = $this->language->get('text_success');
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}Нажмите кнопку сохранения — появится сообщение «Settings saved.». editSetting() записывает в таблицу setting все поля формы, имена которых начинаются с кода module_acme_hello.
Чтение настройки
Сохранённые значения доступны в любом контроллере и модели — и в панели, и на витрине:
$text = $this->config->get('module_acme_hello_text');Частая ошибка
Поле называют text или acme_text — и его значение не сохраняется или потом не находится. Имя каждого поля должно начинаться с кода, переданного в editSetting(), а код модуля — это module_ и имя файла: module_acme_hello_text. По ключу module_acme_hello_status ядро к тому же определяет, включён ли модуль.