Краткое пособие по разработке модулей для Ubilling

Писать дополнительные модули для Ubilling очень просто, давайте рассмотрим процесс написания простейшего модуля на примере модуля показывающего всех пользователей с ихними ФИО, и адресами в виде красивой сортируемой таблички.

Типичный модуль Ubilling размещается в отдельном подкаталоге /modules/general/ и состоит из двух файлов: index.php и module.php. Первый из них является собственно модулем с его исполняемым кодом, второй же - описанием модуля для встроенного диспатчера. Давайте допустим что наш модуль будет называться samplemod и таким образом будет состоять из двух файлов:


Давайте подробно разберем что-же находиться в этих двух мистических файликах.

module.php
  <?php
  $this->registerModule($module, 'main', 'Sample module', 'Sample developer', array('SAMPLE' => __('right for access sample module')));
  ?>

Содержит в себе стандартный набор описывающий то, что модуль имеет класс main (тобишь может размещаться в центральном блоке контента по умолчанию), зовется Sample module, написан разработчиком по имени Sample developer и при своей подгрузке порождает право SAMPLE по которому в последствии мы будем разграничивать доступ к даному модулю. Обратите внимание на конструкцию

__('Строка на английском')

использованную в даном примере в роли описания права на модуль. Функция будет возвращать локализированную строку относительно текущего языка если она найдена в словарном файле. Собственно локализация в Ubilling является gettext подобной.
Все, с файлом описания модуля разобрались, поехали дальше.


index.php
<?php
  // проверяем имеет ли пользователь права на пользование этим модулем
  if (cfr('SAMPLE')) {
 
    //делаем запрос к БД с целью получить логины всех пользователей
    $query="SELECT `login`,`IP` from `users`";
    $alllogins=simple_queryall($query);
 
    //получаем масивы всех Ф.И.О. пользователей и их адресов
    $allrealnames=zb_UserGetAllRealnames();
    $alladdress=zb_AddressGetFulladdresslist();
 
    //проверяем, есть ли вообще у нас пользователи
    if (!empty ($alllogins)) {
 
            //Собираем заголовок таблички для вывода
            $tablecells=wf_TableCell(__('Login'));
            $tablecells.=wf_TableCell(__('IP'));
            $tablecells.=wf_TableCell(__('Real Name'));
            $tablecells.=wf_TableCell(__('Address'));
            $tablerows=wf_TableRow($tablecells, 'row1');
 
        // Перебираем всех пользователей
        foreach ($alllogins as $io=>$eachlogin) {
            $userlogin=$eachlogin['login'];
            $userip=$eachlogin['IP'];
 
            //Собирая для каждого строки таблички
            $tablecells=wf_TableCell($userlogin);
            $tablecells.=wf_TableCell($userip);
            $tablecells.=wf_TableCell(@$allrealnames[$userlogin]);
            $tablecells.=wf_TableCell(@$alladdress[ $userlogin]);
            $tablerows.=wf_TableRow($tablecells, 'row3');
        }
 
        // объявляем как результат табличку с предварительно собранными строками
        // а также шириной в 100%, бордюром в 0 и классом sotrable
        $result=wf_TableBody($tablerows, '100%', '0', 'sortable');
 
    } else {
        //если нету намекаем что их нету
        $result=__('No users found');
    }
 
    // выводим наш результат при помощи функции show_window
    show_window(__('Sample module'), $result);
 
 
  } else {
      // если нет - вываливаем на него ошибку об отказе в доступе
      show_error(__('You cant control this module'));
  }
 
?>

Доступ к нашему модулю мы можем получить при помощи ссылки ?module=samplemod в результате чего мы должны увидеть приблизительно следующее:

Как видите вместо строк Real Name и Address у нас автоматически подставились их языко-зависимые замены из словаря текущей локализации. Не переведенной осталась одна строка Sample module о которой движок локализации пока что ничего не знает. Давайте переведем ее скажем на русский язык для начала.
Сделать это довольно просто - нужно создать файл /languages/russian/samplemod.php следующего содержания:

samplemod.php
<?php
$lang['def']['Sample module'] = 'Модуль для примера';
$lang['def']['Yet another string'] = 'Еще какая-то строка';
?>

После чего мы увидим как строка локализовалась сама по себе в нашем модуле:


Из нестандартных вещей чуждых чистому PHP мы использовали только функции библиотеки api.astral для сборки таблиц при помощи wf_ что не является объязательным, просто выглядит красивее и читабельнее, а также вывод сквозь show_window($title,$data) вместо print() что уже является объязательным для работы шаблонизатора фреймворка.

А что делать, если нашему модулю требуется какая-то библиотека/класс нужная ему одному? Вариантов есть несколько. Первый из них менее красивый но более портабельный - вставить ее прямо внутрь нашего модуля в modules/general/smaplemod/index.php. Второй - просто положить эту библиотеку в директорию modules/engine/. В этом случае она будет подгружена до выполнения нашего модуля. Хорошим тоном в этом случае будет убедиться, что при своей загрузке она не будет производить какого-то вывода и второе - постарайтесь избегать создания больших объектов в этой библиотеке, чтобы избежать деградации производительности в целом. Что подразумевается под этим? Приведем на примере библиотеки, которая описывает некий класс SampleClass и находится в modules/engine/sampleClass.php

sampleClass.php
<?php
 
class SampleClass {
 
  protected $data=array();
 
  public function __construct() {
    $this->loadData();
  }
 
  protected function loadData() {
    $this->data=......
  }
 
}
 
$sampleObject=new SampleClass(); // вот этого тут быть не должно - ему место в modules/general/samplemod/index.php
 
?>

А как добавляются модули на панель задач? Ну там с иконками, правами и опциями? А все так же очень просто - расскладыванием нужных файликов в нужные места. Начиная с релиза 0.8.0 этими местами является директория config/taskbar.d/, а точнее ее подкаталоги. Допустим наш тестовый модуль является с нашей точки зрения отчетом. Также мы хотим, чтобы включался он при помощи необязательной опции alter.ini по имени SAMPLE_ENABLED. Итого ложим файлик sample.ini в директорию config/taskbar.d/reports/

sample.ini
; Идентификатор модуля. Должен быть как минимум уникальным.
ID="samplemod"
; Подпись иконки модуля - будет автоматически локализирована текущей локалью.
NAME="Sample module"
; URL нашего модуля. Не поверите - будет кликабельным :)
URL="?module=samplemod"
; Иконка модуля. Сначала пытается найтись в директории taskbar текущего скина, если не существует - в глобальном skins/taskbar.
ICON="goat.gif"
; Право которое требует модуль. Ну как минимум право которое требуется для показа иконки.
NEED_RIGHT="SAMPLE"
; Опция конфига alter.ini требуемая для показа иконки таскбара.
NEED_OPTION="SAMPLE_ENABLED"
; Данный параметр сигнализирует, что опция является необязательной. 
; Если удалить данный параметр - панель задач будет орать о недостающей опции.
UNIMPORTANT=1
; Тип елемента. В нашем случае это icon - типичная иконка с подписью. Есть еще widget но о этом позже.
TYPE="icon"

А что же с виджетами, и как они вообще выглядят? А вот как-то так.

development.txt · Последние изменения: 2017/10/07 12:00 — nightfly
 
За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki