[comment]: # aside:1

[comment]: # ({b311df1e-8fe7205c})
# Создание модуля (руководство)

[comment]: # ({/b311df1e-8fe7205c})

[comment]: # ({98067368-5fb5b83a})
Эта пошаговая инструкция показывает, как создать простой модуль веб-интерфейса Zabbix.
Вы можете скачать все файлы этого модуля в виде ZIP-архива: [MyAddress.zip](../../../../assets/en/devel/modules/examples/MyAddress.zip).

[comment]: # ({/98067368-5fb5b83a})

[comment]: # ({b971a521-5ce71b9d})
### Что вы создадите

В ходе этого руководства вы сначала создадите модуль веб-интерфейса, который добавляет новый раздел меню *My Address*, а затем преобразуете его в [более продвинутый](#part-iii--module-action) модуль веб-интерфейса, который выполняет HTTP-запрос к *https://api.seeip.org* и отображает ответ — IP-адрес вашего компьютера — на новой странице в новом разделе меню *My Address*.

Вот как будет выглядеть готовый модуль:

![](../../../../assets/en/devel/modules/tutorials/module/my_address_finished.png){width="600"}

[comment]: # ({/b971a521-5ce71b9d})

[comment]: # ({a5c86d2c-8c2bcd9e})
### Часть I - Новый раздел меню

[comment]: # ({/a5c86d2c-8c2bcd9e})

[comment]: # ({9c416cbb-1d4de634})
##### Добавление пустого модуля во веб-интерфейс Zabbix

1. Создайте каталог *MyAddress* в каталоге *modules* вашей установки веб-интерфейса Zabbix (например, *zabbix/ui/modules*).

2. Создайте файл *manifest.json* с базовыми метаданными модуля (см. описание поддерживаемых [параметров](../file_structure/manifest)).

**ui/modules/MyAddress/manifest.json**

```json
{
    "manifest_version": 2.0,
    "id": "my-address",
    "name": "My IP Address",
    "version": "1.0",
    "namespace": "MyAddress",
    "description": "My External IP Address."
}
```

3. В веб-интерфейсе Zabbix перейдите в раздел *Administration → General → Modules* и нажмите кнопку *Scan directory*.

![](../../../../assets/en/devel/modules/tutorials/widget/scan_dir.png)

4. Найдите новый модуль *My IP Address* в списке и нажмите на гиперссылку "Disabled", чтобы изменить статус модуля с "Disabled" на "Enabled" (если модуль не отображается в списке, см. раздел [troubleshooting](/manual/extensions/frontendmodules#installation)).

![](../../../../assets/en/devel/modules/tutorials/module/module_register.png){width="600"}

Теперь модуль зарегистрирован во веб-интерфейсе. Однако он пока не виден, потому что вам еще нужно определить функциональность модуля.
После того как вы добавите содержимое в каталог модуля, изменения сразу станут видны во веб-интерфейсе Zabbix после обновления страницы.

[comment]: # ({/9c416cbb-1d4de634})

[comment]: # ({db062f15-d88b8114})
##### Создание раздела меню

1. Создайте файл *Module.php* в каталоге *MyAddress*.

Этот файл реализует новый класс *Module*, который наследуется от стандартного класса *CModule*.
Класс *Module* добавит новый раздел меню *My Address* в главное меню.

Метод *setAction()* задает действие, которое будет выполнено при нажатии на раздел меню.
Для начала можно использовать предопределенное действие *userprofile.edit*, которое откроет страницу *User profile*.
В [части III](#part-iii--module-action) этого руководства вы узнаете, как создать пользовательское действие.

**ui/modules/MyAddress/Module.php**

```php
<?php

namespace Modules\MyAddress;

use Zabbix\Core\CModule,
    APP,
    CMenuItem;

class Module extends CModule {

    public function init(): void {
        APP::Component()->get('menu.main')
            ->add((new CMenuItem(_('My Address')))
            ->setAction('userprofile.edit'));
    }
}
```

:::noteclassic
Вы можете заменить `'userprofile.edit'` на другие действия, например, `'charts.view'` (открывает пользовательские графики), `'problems.view'` (открывает *Monitoring → Problems*) или `'report.status'` (открывает отчет *System information*).
:::

3. Обновите веб-интерфейс Zabbix. Теперь в нижней части главного меню Zabbix появился новый раздел *My Address*.
Нажмите *My Address*, чтобы открыть страницу *User profile*.

![](../../../../assets/en/devel/modules/tutorials/module/my_address_top_menu.png){width="600"}

[comment]: # ({/db062f15-d88b8114})

[comment]: # ({89dbfda8-5c3fc480})
### Часть II - Изменение расположения раздела меню

В этой части вы переместите раздел меню *Мой адрес* в раздел *Мониторинг*, а затем добавите в него вложенное меню.
В результате пользователи смогут получить доступ к двум страницам подменю из раздела меню *Мониторинг → Мой адрес*.

1. Откройте и отредактируйте файл *Module.php*.

**ui/modules/MyAddress/Module.php**

```php
<?php

namespace Modules\MyAddress;

use Zabbix\Core\CModule,
    APP,
    CMenuItem;

class Module extends CModule {

    public function init(): void {
        APP::Component()->get('menu.main')
            ->findOrAdd(_('Monitoring'))
            ->getSubmenu()
            ->insertAfter(_('Discovery'),
                (new CMenuItem(_('My Address')))->setAction('userprofile.edit')
            );
    }
}
```

2. Обновите интерфейс Zabbix. Разверните раздел меню *Мониторинг* и обратите внимание, что раздел *Мой адрес* теперь расположен под разделом *Обнаружение*.

![](../../../../assets/en/devel/modules/tutorials/module/my_address_monitoring.png){width="600"}

3. Чтобы добавить вложенные страницы в раздел меню *Мой адрес*, снова откройте и отредактируйте файл *Module.php*.

На этом этапе создаются два подраздела:

- *Внешний IP*, который выполняет новое действие «my.address», которое будет определено на следующих шагах;
- *Профиль пользователя*, который выполняет предопределенное действие «userprofile.edit», чтобы открыть страницу *Профиль пользователя*.

Обратите внимание, что для вложенного меню вам необходимо использовать класс *CMenu* в дополнение к классам, использованным на предыдущих шагах.

**ui/modules/MyAddress/Module.php**

```php
<?php

namespace Modules\MyAddress;

use Zabbix\Core\CModule,
    APP,
    CMenu,
    CMenuItem;

class Module extends CModule {

    public function init(): void {
        APP::Component()->get('menu.main')
            ->findOrAdd(_('Monitoring'))
            ->getSubmenu()
            ->insertAfter(_('Discovery'),
                (new CMenuItem(_('My Address')))->setSubMenu(
                    new CMenu([
                        (new CMenuItem(_('External IP')))->setAction('my.address'),
                        (new CMenuItem(_('User profile')))->setAction('userprofile.edit')
                    ])
                )
            );
    }
}
```

4. Обновите интерфейс Zabbix. Обратите внимание, что раздел меню *Мой адрес* теперь содержит меню третьего уровня с двумя страницами — *Внешний IP* и *Профиль пользователя*.

![](../../../../assets/en/devel/modules/tutorials/module/my_address_nested.png){width="600"}

[comment]: # ({/89dbfda8-5c3fc480})

[comment]: # ({6061bdad-8798eff6})
### Часть III — Действие модуля

Действие реализовано в двух файлах — *actions/MyAddress.php* и *views/my.address.php*.
Файл ***actions/MyAddress.php*** отвечает за реализацию бизнес-логики, а файл ***views/my.address.php*** отвечает за представление.

1. Создайте каталог *actions* в каталоге *MyAddress*.

2. Создайте файл *MyAddress.php* в каталоге *actions*.

Логика действий будет определена в классе *MyAddress*.
Этот класс действий будет реализовывать четыре функции: *init()*, *checkInput()*, *checkPermissions()* и *doAction()*.
Интерфейс Zabbix вызывает функцию *doAction()*, когда запрашивается действие.
Эта функция отвечает за бизнес-логику модуля.

::: noteimportant
Данные должны быть организованы в виде ассоциативного массива.
Массив может быть многомерным и содержать любые данные, ожидаемые представлением.
:::

**ui/modules/MyAddress/actions/MyAddress.php**

```php
<?php

namespace Modules\MyAddress\Actions;

use CController,
    CControllerResponseData;

class MyAddress extends CController {

    public function init(): void {
        $this->disableCsrfValidation();
    }

    protected function checkInput(): bool {
        return true;
    }

    protected function checkPermissions(): bool {
        return true;
    }

    protected function doAction(): void {
        $data = ['my-ip' => file_get_contents("https://api.seeip.org")];
        $response = new CControllerResponseData($data);
        $this->setResponse($response);
    }
}
```

3. Создайте новый каталог *views* в каталоге *MyAddress*.

4. Создайте файл *my.address.php* в каталоге *views* и определите представление модуля.

Обратите внимание, что переменная `$data` доступна в представлении без ее специального определения.
Платформа автоматически передает ассоциативный массив в представление.

**ui/modules/MyAddress/views/my.address.php**

```php
<?php

(new CHtmlPage())
    ->setTitle(_('The HTML Title of My Address Page'))
    ->addItem(new CDiv($data['my-ip']))
    ->show();
```

5. Действие модуля должно быть зарегистрировано в файле *manifest.json*. Откройте *manifest.json* и добавьте новый объект «actions», который содержит:

-   клавиша действия с названием действия, написанным строчными буквами (a-z) и словами, разделенными точками (например, `my.address`);
-   имя класса действия («MyAddress») как значение ключа «class» объекта «my.address»;
-   имя представления действия («my.address») как значение ключа «view» объекта «my.address».

**ui/modules/MyAddress/manifest.json**

```json
{
    "manifest_version": 2.0,
    "id": "my-address",
    "name": "My IP Address",
    "version": "1.0",
    "namespace": "MyAddress",
    "description": "My External IP Address.",
    "actions": {
        "my.address": {
            "class": "MyAddress",
            "view": "my.address"
        }
    }
}
```

6. Обновите интерфейс Zabbix. Нажмите *Мой адрес → Внешний IP*, чтобы увидеть IP-адрес вашего компьютера.

![](../../../../assets/en/devel/modules/tutorials/module/my_address_finished.png){width="600"}

[comment]: # ({/6061bdad-8798eff6})
