Користувальницькькі налаштування

Налаштування сайту


development

Розбіжності

Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.

Посилання на цей список змін

Порівняння попередніх версій Попередня ревізія
Попередня ревізія
development [2017/10/07 12:00]
development [2023/06/16 14:18] (поточний)
borisov
Рядок 1: Рядок 1:
 +====== Короткий посібник із розроблення модулів для Ubilling ======
  
 +Писати додаткові модулі для Ubilling дуже просто, розгляньмо процес написання найпростішого модуля на прикладі модуля, що показує всіх користувачів з їхніми ПІБ та адресами у вигляді гарної сортувальної таблички.
 +
 +Типовий модуль Ubilling розміщується в окремому підкаталозі **/modules/general/** і складається з двох файлів: **index.php** і **module.php**. Перший із них є власне модулем із його виконуваним кодом, другий же - описом модуля для вбудованого диспатчера. Давайте припустимо, що наш модуль називатиметься samplemod і таким чином складатиметься з двох файлів:\\
 +\\
 +{{:samplemod.png?|}}
 +\\
 +
 +Давайте детально розберемо що-ж знаходиться в цих двох містичних файликах.\\
 +
 +<file php module.php>
 +  <?php
 +  $this->registerModule($module, 'main', 'Sample module', 'Sample developer', array('SAMPLE' => __('right for access sample module')));
 +  ?>
 +</file>
 +
 +Містить у собі стандартний набір, який описує те, що модуль має клас **main** (тобто може розміщуватися в центральному блоці контенту за замовчуванням), зветься **Sample module**, написаний розробником на ім'я **Sample developer** і під час свого довантаження породжує право **SAMPLE**, за яким згодом ми розмежовуватимемо доступ до цього модуля. Зверніть увагу на конструкцію <code>__('Рядок англійською')</code> використану в цьому прикладі в ролі опису права на модуль. Функція повертатиме локалізований рядок відносно поточної мови, якщо він знайдений у словниковому файлі. Власне локалізація в Ubilling є подібною до gettext.\\
 +Все, з файлом опису модуля розібралися, поїхали далі.\\
 +\\
 +\\
 +
 +
 +<file php 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'));
 +  }
 +
 +?>
 +
 +</file>
 + 
 +Доступ до нашого модуля ми можемо отримати за допомогою посилання **?module=samplemod**, в результаті чого ми повинні побачити приблизно таке:\\
 +
 +{{:samplemod2.png?|}}
 +
 +Як бачите, замість рядків **Real Name** і **Address** у нас автоматично підставилися їхні мовно-залежні заміни зі словника поточної локалізації. Не перекладеним залишився один рядок **Sample module**, про який рушій локалізації поки що нічого не знає. Давайте перекладемо його скажімо російською мовою для початку.\\\
 +Зробити це досить просто - потрібно створити файл **/languages/russian/samplemod.php** такого змісту:
 +
 +<file php samplemod.php>
 +<?php
 +$lang['def']['Sample module'] = 'Модуль для прикладу';
 +$lang['def']['Yet another string'] = 'Ще якийсь рядок';
 +?>
 +</file>
 +
 +Після чого ми побачимо як рядок локалізувався сам по собі в нашому модулі:\\
 +
 +{{:samplemod3.png?|}}
 +
 +\\
 +З нестандартних речей, чужих чистому PHP, ми використовували тільки функції бібліотеки** api.astral** для збирання таблиць за допомогою **wf_**, що не є об'язковою, просто виглядає красивіше та читабельніше, а також висновок крізь **show_window($title,$data)** замість **print()**, що вже є об'язковою для роботи шаблонізатора фреймворка.\\
 +
 +А що робити, якщо нашому модулю потрібна якась бібліотека/клас потрібна йому одному? Варіантів є кілька. Перший з них менш красивий, але більш портабельний - вставити її прямо всередину нашого модуля в **modules/general/smaplemod/index.php**. Другий - просто покласти цю бібліотеку в директорію **modules/engine/**. У цьому разі вона буде довантажена до виконання нашого модуля. Хорошим тоном у цьому випадку буде переконатися, що під час свого завантаження вона не буде виробляти якогось виводу, і друге - постарайтеся уникати створення великих об'єктів у цій бібліотеці, щоб уникнути деградації продуктивності загалом. Що мається на увазі під цим? Наведемо на прикладі бібліотеки, яка описує якийсь клас SampleClass і знаходиться в **modules/engine/sampleClass.php**
 +
 +<file 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
 +
 +?>
 +</file>
 +
 +Також чудовим (**і рекомендованим!**) способом може бути поміщення вашої бібліотеки в **api/libs/**, звідки її може підхопити автозавантажувач, якщо ім'я класу створюваного об'єкта відповідає імені бібліотеки з префксом "**api.**" у лаверкейсі. Для прикладу вище це має бути файл **api/libs/api.sampleclass.php**. Під час створення об'єкта $sampleObject=new SampleClass(); цю бібліотеку буде автоматично завантажено, і вам взагалі нічого не потрібно для цього робити. Ця механіка з'явилася починаючи з релізу Ubilling 0.8.6 Chainsaw.
 +
 +А як додаються модулі на панель завдань? Ну там з іконками, правами та опціями? А все так само дуже просто - розкладанням потрібних файликів у потрібні місця. Починаючи з релізу 0.8.0 цими місцями є директорія **config/taskbar.d/**, а точніше її підкаталоги. Припустимо, наш тестовий модуль є з нашої точки зору звітом. Також ми хочемо, щоб вмикався він за допомогою необов'язкової опції [[alteriniconf|alter.ini]] на ім'я SAMPLE_ENABLED. Разом кладемо файлик sample.ini в директорію **config/taskbar.d/reports/**
 +
 +<file ini 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"
 +</file>
 +
 +А що ж із віджетами, і як вони взагалі виглядають? А ось якось так [[taskbarwidgets|так]].
development.txt · Востаннє змінено: 2023/06/16 14:18 повз borisov