NPJ next : Документация/Модули

Сторонние модули для НПЖ (third-party modules)

Оглавление документа

Введение


Ядро НПЖ — тесносплетённая структура, самостоятельное добавление функционала в которую сопряжено с вопросами целостности и проблемами перехода на более свежие версии ядра. Поэтому НПЖ поддерживает несколько способов наращивания функционала и один из них — расширение через модули --не касается «просто интеграции в существующую систему», а предназначен для подключения дополнительного функционала в НПЖ.

Этот документ описывает способы расширения функционала НПЖ через модули и содержит (возможно) краткую инструкцию по разработке модуля.

Что такое «модуль для НПЖ»?


Модуль в НПЖ — это независимая подструктура в рамках ПО НПЖ, реализующая какой-то специфичный, расширенный функционал.
Файлы модуля находятся за пределами папок core/ и npj/ дистрибутива и поэтому толерантны к обновлению ядра.

Программные механизмы модуля взаимодействуют с ядром по заранее определённым схемам, позволяя добиться разной степени интеграции модуля в среду НПЖ.

Зачем они вообще нужны, эти модули


Модули используются для решения двух типов задач:

Какие уже существуют модули


На момент написания данного документа существует уже более пяти модулей, большая часть которых используется в конкретных инсталляциях. Модуль NPJ Trako — напротив, является универсальным и переносимым.

Кроме существующих, планируется разработка модулей:

Устройство модуля


Устройство модуля можно будет разобрать самостоятельно, скачав один или два из наших демо-модулей.
Пока это невозможно, поскольку инфраструктура находится в стадии рефакторинга.
[to be supplied.]

Конфигурация модуля


Модуль подключается в НПЖ через свой файл конфигурации.
Все способы подключения базируются на внесении в файл config_modules.php строк
<?
  
// module TRAKO
  
include( "trako/npj_config.php" );
?>

Эти строки указывают НПЖ на путь к конфигурационному файлу данного модуля, внутри которого и определяются все дальнейшие детали подключения.

Общая структура конфигурационного файла


Для всех способов подключения уместна общая структура файла, включающая:
<?
  $this
->modules"trako" ] = array( // #1
        
"name"              => "Bug/issue/incident tracker TRAKO"// #2
        
"module_dir"        => "trako/"// #3
        
"messageset_prefix" => "Trako"//#4
        
"classname"         => "ModuleTrako"//#5
                                  
);
?>

Рассмотрим строки попунктно:

  1. trako — рабочий псевдоним модуля. NB: для подключения «как субпространства» необходимо, чтобы оно совпадало с “subspace”
  2. Bug/issue/incident tracker TRAKO — произвольное наименование модуля, используемое для отладочных и визуально-опознавательных целей
  3. trako/ — имя подкаталога в директории для модулей, который содержит все файлы модуля. Имя подкаталога заканчивается слэшем /
  4. Trako — наименование message_set, соответствующего модулю. Этот message_set хранится (в нашем случае) в каталоге trako/messagesets/
  5. ModuleTrako — имя класса (который может лежать в каталоге classes/ модуля или где-нибудь ещё


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

Подключение модуля как субпространства


Для подключения модуля «как субпространства» необходимо указать следующие дополнительные параметры конфигурации:
<?
  $this
->modules["trako"]["subspace"] = "trako";
?>

Важно, что subspace должно совпадать с псевдонимом модуля.

В таком случае вы можете передать управление в модуль в любом месте, дописав в URL или НПЖ-адрес указанное субпространство, например: npj-trako@pixelapes:Panel/Trako.

Впрочем, вы можете ограничить модуль только «корнем узла», прописав:
<?
  $this
->modules["trako"]["subspace_root_only"] = true;
?>

Такое подключение модуля не обеспечивает «прозрачности» работы стандартных механизмов НПЖ в этом субпространстве, зато даёт богатые возможности по встраиванию совершенно стороннего функционала.

Подключение модуля как аккаунт (прозрачный модуль)


Вы можете подключить модуль «как аккаунт» — чтобы вся работа с НПЖ-объектами в каком-то аккаунте «проходила» через ваш модуль.
В таком случае дополнительные параметры конфигурации выглядят как:
<?
  $this
->modules["demo-module"]["root"] = "demo@pixelapes";
?>

Важно, что таковой аккаунт должен существовать, иначе всё, что вы получите в своё распоряжение — ошибку 404.
Такое подключение делает возможным для модуля оставаться «прозрачным» для НПЖ, перехватывая лишь специфические запросы.

Модуль как «фантомный внешний узел»


Вы можете подключить модуль как «фантомный внешний узел» — чтобы вся работа с НПЖ-объектами в пространстве @phantom/node (где node — это ваш узел, а phantom — некоторое «фантомное» имя для модуля) «проходила» через ваш модуль.

Это третий способ подключения модулей.

Что нужно сделать для этого:
<?
  $this
->modules["demo-module"]["as_foreign"] = array( "sample""maple" );
?>

Подключение модуля несколькими способами


К сожалению, с точки зрения НПЖ каждое подключение модуля возможно только одним из изложенных способов.
Но мы можем этого избежать, написав примерно такой код:
<?
  $this
->modules["channels"] = array(
        
// this module is subspace module                         
        
"subspace"          => "channels"// must be strict equal to modules[<SUBSPACE>] subspace

        
"name"              => "Агрегатор (RSS, Mailbox)",
        
"module_dir"        => "channels/",
        ...
                                  );
  
// helping module instance for invasion on node-level basis
  
$this->modules["channels-integration"] = $this->modules["channels"];
  
$this->modules["channels-integration"]["as_foreign"] = array( "rss""mailbox""file" );
  unset( 
$this->modules["channels-integration"]["subspace"] );
?>

Как сделать свой модуль?


Пока видится примерно следующая схема с такими шагами:

  1. Выполнить проектирование модуля: подробно описать адресную схему модуля и определиться с типом подключения.
  2. Скачать демо-модуль наиболее соответствующий вашему проекту
  3. Подключить модуль в узел, используя config_modules.php
  4. Нарастить ваш специфический функционал поверх кода демо-модуля

[to be supplied.]

Программное взаимодействие модуля и НПЖ

Доступ к Actions модуля из документов НПЖ


Да, это возможно.
Для этого нужно подключить модуль (лучше в субпространство) и писать в документах что-то вроде:



Подробнее — чуть позже.
[to be supplied.]

Доступ к модулю из программного окружения НПЖ


  1. Если мы находимся «внутри» модуля (в особенности модуля субпространства), то мы можем получить его экземпляр вот так:
    <?
          $module_instance 
    = &$this->rh->modules["trako"]["&instance"];
          
    ?>

  2. Если НПЖ-объект «ассоциирован» с модулем (т.е. находится в «модуль-аккаунте»), то мы можем получить вот что:
    <?
          $module_name 
    $npj_object->module// "trako"
          
    $module_instance = &$npj_object->module_instance;
          
    ?>

Управление доступностью модулей субпространств


По-умолчанию, модуль субпространства доступен везде.
Можно это поведение ограничить для определённого класса аккаунтов опцией modules_override = array( “trako” ).
В массиве указывается перечень доступных для данного класса модулей.

«Прозрачный» модуль: внедрение в цикл «редактирование-сохранение»


Мы рассмотрим только случай внедрения для модуля, привязанного к аккаунту.
Для непрозрачного модуля субпространства это гораздо более запутано. На примере можете посмотреть в NPJ Trako.

Всё очень просто: у вашего класса модуля — потомка класса NpjModule необходимо override метод SpawnHelper, сделать так, чтобы он создавал ваш собственный хелпер (например, HelperTrakoIssue для рапортов в Траке) и возвращал его. А уже в хелпере модифицировать и построение форм редактирования, и цикл сохранения в БД.

Подробнее про архитектуру Helper: /Документация/АрхитектураХелперовПсевдотипыЗаписей

Подводя итог


Конечно, этой документации ещё далеко до полной версии, но она, надеемся, позволит хоть как-то облегчить первый шок от встречи с модулями в НПЖ.

Если вы пробуете создать модуль для НПЖ, и у вас не получается — спрашивайте!