Підтримка віджетів для панелі завдань, була додана ще в релізі Ubilling 0.8.0, але як могло здатися, зроблена вона була настільки дивним і незбагненним чином, що люди, які намагалися їх писати, ставали іншими. Тому вважається, що підтримки віджетів немає. А насправді є, і вона досить проста і зручна, якщо розібратися.
А чого взагалі може робити віджет? Та загалом усе, що й будь-який інший модуль системи. Аж до повної модифікації зовнішнього вигляду і поведінки самої панелі завдань на льоту (див. WIDGET_TBBLUR або скажімо WIDGET_PSYCHO). Але в нормі, це розраховано на відображення якоїсь корисної статистики. Ні, ми не вважаємо версію PHP, модель процесора або версію Apache “корисною” в тому контексті, що вона повинна постійно висіти перед на панелі завдань і вимагати постійного моніторингу. Ага, хтось за ніч підмінив CPU і перекомпілював PHP - злочин розкрито. Але якщо вам так спичить - то так, все робиться в кілька рядків без проблем.
Несподівано, але віджет починається з елемента таскбара, з відповідним типом. Подивимося на прикладі найпростішого семплового віджета з config/modules.d/widgets/sample.ini, який просто виводить якийсь рядок.
ID="widget_sample" CODEFILE="widget_sample.php" NEED_RIGHT="" NEED_OPTION="WIDGET_SAMPLE" UNIMPORTANT=1 TYPE="widget"
Дивлячись на це все, не складно помітити, що ідентифікатором віджета є widget_sample, код віджета має бути розміщений у widget_sample.php, для своєї роботи він не вимагає ніяких додаткових прав і вимагає необов'язкової (UNIMPORTANT) опції WIDGET_SAMPLE=1 для свого ввімкнення. Ну і найголовніше, має TYPE не icon, а widget, що має сигналізувати панелі завдань, що тут варто чогось виконувати. Так, опис елемента таскбара може лежати в якій завгодно категорії modules.d - йому без різниці. Просто widgets знаходиться за замовчуванням “зверху”. Винятком є сам файл коду, описаний у CODEFILE, - він таки має знаходитися в config/taskbar.d/widgets/.
А як же запитаєте ви, система дізнається, що з цього самого widget_sample.php потрібно виконувати? А дуже просто, давайте заглянемо в нього:
<?php class widget_sample extends TaskbarWidget { public function render() { $result = __('Sample text'); return ($result); } } ?>
З чого робимо висновок, що базовим для всієї цієї механіки є успадкування класом з ім'ям widget_sample (так, це те, що описано в опції ID віджету, тобто його внутрішній унікальний ідентифікатор) якогось класу TaskbarWidget і перевизначення роботи методу render(). Так, усе виведення даних віджетом має відбуватися у вигляді значення, що повертається від виклику цього самого render(). А що якщо нам хочеться вивести не просто голий текст, а його ж, але в стандартній, і якось красиво оформленій окремій області? Та без проблем. Для цього варто перед return() методу render() пропустити наші дані через уже дбайливо приготований для вас протектед метод widgetContainer() (так, його перевизначати вам у разі потреби теж ніхто не забороняє). Який вигляд це має мати в коді, і що ми отримаємо в результаті? А ось щось таке:
<?php class widget_sample extends TaskbarWidget { public function render() { $result = $this->widgetContainer(__('Sample text')); return ($result); } } ?>
І це все? Так - це все. Більше там ніякої іншої, крутої магії не відбувається.
Окей, якщо незрозуміло, як можна обійтися одним автовикликуваним методом render(), для розв'язання якихось практичних завдань, давайте під шумок напишемо ще якийсь віджет, скажімо такий, що надсилає SMS-ки кудись там. Заодно і пхнемо його в основне дерево коду - раптом комусь знадобитися? ;)
Отже, як уже було згадано вище - віджет починається з опису елемента таскбара в config/taskbar.d/widgets/:
ID="widget_fastsms" CODEFILE="widget_fastsms.php" NEED_RIGHT="SENDDOG" NEED_OPTION="WIDGET_FASTSMS" UNIMPORTANT=1 TYPE="widget"
Давайте перевіримо, чого тепер у нас на панелі завдань? Ухти - вона нам ніби натякає, що ми щось забули ;)
Окей, давайте створимо наступний config/taskbar.d/widgets/widget_fastsms.php ось із якимось таким змістом:
<?php class widget_fastsms extends TaskbarWidget { /** * Contains system alter config as key=>value * * @var array */ protected $altCfg = array(); /** * UbillingSMS object placeholder * * @var object */ protected $sms = ''; const TASKBAR_URL = '?module=taskbar'; /** * Creates new widget_fastsms instance * * @return void */ public function __construct() { $this->loadAlter(); $this->initSMS(); } /** * Loads system alter config into protected prop for further usage * * @global object $ubillingConfig * * @return void */ protected function loadAlter() { global $ubillingConfig; $this->altCfg = $ubillingConfig->getAlter(); } /** * Initalizes system SMS sending abstraction layer * * @return void */ protected function initSMS() { $this->sms = new UbillingSMS(); } /** * Returns SMS sending form * * @return string */ protected function smsSendForm() { $result = ''; $inputs = wf_TextInput('fastsmsnumber', __('Mobile'), '', true, '20'); $inputs.= wf_TextArea('fastsmsmessage', '', '', true, '30x5'); $inputs.= wf_CheckInput('fastsmstranslit', __('Forced transliteration'), true, true); $inputs.= wf_Submit(__('Create')); $form = wf_Form('', 'POST', $inputs, 'glamour'); //displaying sending form as button or inline taskbar form if ($this->altCfg['WIDGET_FASTSMS'] == 1) { $result = wf_modalAuto(wf_img('skins/icon_mobile.gif', __('Create new SMS')) . ' ' . __('Send SMS'), __('Create new SMS'), $form, 'ubButton'); } if ($this->altCfg['WIDGET_FASTSMS'] == 2) { $result = $form; } return ($result); } /** * Catches form sending request and performs SMS queue storing * * @return void */ protected function catchSMSSending() { if (wf_CheckPost(array('fastsmsnumber', 'fastsmsmessage'))) { $translitFlag = (wf_CheckPost(array('fastsmstranslit'))) ? true : false; $this->sms->sendSMS($_POST['fastsmsnumber'], $_POST['fastsmsmessage'], $translitFlag, 'WIDGET_FASTSMS'); //preventing sms resending on page refresh rcms_redirect(self::TASKBAR_URL); } } /** * Runs and renders widget code * * @return string */ public function render() { $result = ''; if ($this->altCfg['SENDDOG_ENABLED']) { //performs sms sending if required $this->catchSMSSending(); //rendering sending form $result.=$this->widgetContainer($this->smsSendForm()); } else { $messages = new UbillingMessageHelper(); $result = $messages->getStyledMessage(__('SendDog') . ' ' . __('Disabled') . ' :(', 'error'); } return ($result); } } ?>
Як нескладно помітити, форма відсилання SMS реагує на значення опції WIDGET_FASTSMS і може показувати форму як у вигляді кнопки зі спливаючим модальним вікном (WIDGET_FASTSMS=1), так і безпосередньо відразу в таскбарі (WIDGET_FASTSMS=2). Невже це якось виглядає, і ще працює? Несподівано, але так.
Ви можете увімкнути/вимкнути якісь зі стокових віджетів, по черзі або разом, щоб поспостерігати, як вони працюють.
; Показує поточний аптайм системи WIDGET_UPTIME=1 ; Віджет швидкого надсилання SMS, ми його там трохи вище на ходу писали. Що вже забули? WIDGET_FASTSMS=1 ;Показує графічок за фінансовим звітом, за останній місяць WIDGET_FINANCE=1 ; Радує ваш персонал, на рівні "мамо, коли мене відпустить?" WIDGET_PSYCHO=1 ; Власне описаний вище семпловий віджет, який просто виводить рядок. WIDGET_SAMPLE=1 ; Робить іконкам панелі завдань ефект "зір псується". WIDGET_TBBLUR=1 ; Стильно чорно-білить іконки панелі завдань. WIDGET_TBBW=1 ; Іконки панелі завдань можна потягнути кудись і обґрунтувати цим чому "робота не йде" WIDGET_TBDRAG=1 ; Хрестики-нулики, а ви чого очікували? WIDGET_TICTACTOE=1 ; Може комусь дуже хочеться постійно моніторити сумарний трафік, утилізований його користувачами? WIDGET_TRAFFIC=1 ; Конвертер валют. WIDGET_CURRENCY=1 ; З шансом 10% кричить про meabeab-а в пошуках BONK-a! ; https://www.youtube.com/watch?v=m0i8IBZklZg WIDGET_MEABEAB=1