Показати сторінкуСтарі ревізіїПосилання сюдиЕкспорт до PDFПовернутися наверх Ця сторінка доступна тільки для перегляду. Ви можете продивитися вихідний текст, але не можете змінювати його. Якщо ви вважаєте, що це не вірно, зверніться до адміністратора. ====== Підпрограми calls.pm ====== ====== Глобальні змінні ====== * $ses::ajax - встановлений, якщо запит є ajax. * $ses::cookie - поточні куки, наприклад $ses::cookie->{debug}. * $ses::http_prefix - 'http:/%%/'%% або 'https:/%%/'%%. * $cfg::img_url - 'https://nodeny.com.ua/i'. * $ses::ip - ip адміна/клієнта, який залогінився в веб-інтерфейсі. * $ses::server - ім'я сервера витягнутого з адресного рядка, наприклад, nodeny.com.ua в https://nodeny.com.ua/cgi-bin/stat.pl. * $ ses:: t - поточний час, unix timestamp. * $ses::day_now - поточний день. * $ses::mon_now - поточний місяць. * $ses::year_now - поточний рік. * $ses::auth - посилання на дані поточної авторизації в адмінці: * $ses::auth->{auth} встановлений, якщо адмін/клієнт авторизований. * $ses::auth->{uid} - id адміна/клієнта * $ses::auth->{role}: 'admin' - авторизований адмін, 'user' - клієнт * $ses::auth->{ses} - рядок-сесія * $ses::auth->{trust} - чи довірена сесія * $ses::unikey - ключ до даних у таблиці webses_data, які будуть додані до поточних даних, переданих браузером. У будь-який модуль, крім авторизації, можна потрапити лише будучи авторизованим. Авторизація буває довіреною та недовіреною. Якщо джерело авторизації надійне, наприклад, авторизація за логіном та паролем, він встановлює параметр trust в 1. Небезпечні функції слід дозволяти тільки при довіреному з'єднанні: <code> $ses::auth->{trust} or Error('З'єднання не довірене. Необхідно перелогінитися'); </code> До клієнтської статистики може потрапити не тільки клієнт, а й адміністратор від його імені, тому в деяких випадках бажано виводити різну інформацію для адміна та клієнта, а також фіксувати, що саме адміністратор виконав дію: <code> if( 1 + 1 > 3 ) { Error( Adm->id? 'Паніка! Perl неправильно вважає' : 'Сервіс тимчасово недоступний'); } # Поповнимо рахунок клієнта, при цьому Pay_to_DB сама проставит автора Pay_to_DB(uid=>$uid, cash=>10, category=>1); </code> ====== POST/GET параметри ====== Отримати параметри, надіслані через браузер, можна за допомогою ses::input: http://xxx/?a=test&b=0&uid=33 <code> if( ses::input('a') eq 'test' && ses::input_exists('b') ) { # Умова спрацює т.к. в url a = test і параметр b присутній # Параметр uid про всяк випадок примусово приведемо до цілого числа my $uid = ses::input_int('uid'); $uid or Error('Введіть ціле число, що не дорівнює нулю'); } </code> Хеш усіх переданих параметрів зберігається в $ ses:: input_orig: <code> # Якщо параметр yes не існує або не встановлено, # відредагуємо самі на себе і пошлемо всі параметри + встановимо yes ses::input('yes') or url->redirect( { %$ses::input_orig, yes=>1 } ); </code> Існує альтернативний спосіб передачі параметрів - дані записуються в базу даних таблицю [[Db_tables#webses_data|webses_data]], доступ до яких здійснюється за ключом unikey таблиці. Взагалі через дану таблицю можуть передаватися будь-які дані, а передача параметрів від браузера - одна з фіч. На прикладі покажемо навіщо потрібний такий механізм. Припустимо, клієнт надсилає дані. Модуль їх перевіряє. Знаходить помилку. Якщо вивести помилку, клієнт буде роздратований тим, що ввів багато даних і йому знову знадобиться їх вводити. Тому передані дані записуються в webses_data і відбувається редирект на сторінку введення, при цьому параметр _unikey встановлюється значення поля unikey збережених даних. Перед завантаженням модуля, якщо calls.pm бачить параметр _unikey, він автоматично витягує з БД зв'язану з ключем рядок і дешифрує її змінну $ses::data. Далі, якщо існує ключ $ses::data->{-input}, то calls.pm «дає вигляд», що браузер надіслав POST/GET дані, що знаходяться $ses::data->{-input}. Найчастіше ці події відбуваються прозоро, тобто. не потрібно думати про ключ -input. Наприклад, редирект завжди здійснюється через webses_data: <code> $Url->redirect(a=>'main', uid=>15); </code> В даному випадку відбудеться запис {a=>'main', uid=>15} у webses_data, після чого відбудеться перехід http::%%//%%xxx/?_unikey=yyyyyy. Тут yyyyyy – ключ до даних, записаних у таблицю. Якщо ми вже заговорили про редирект, то відзначимо 2 корисні його параметри -made і -error. Перший призначений для того, щоб вивести повідомлення вгорі сторінки після редиректу, при цьому якщо буде встановлено -error, то червоним кольором: <code> $Url->redirect(a=>'main', -error=>1, -made=>'Помилкова операція. Редиректимося на титульну сторінку '); </code> ====== Підпрограми модуля main ====== ToLeft, ToRight, ToTop Виводять дані в ліву, праву і відповідно у верхню частину html-сторінки, що формується. <code> ToLeft 'Текст зліва'; </code> **MessageBox** виводить повідомлення у рамці <code> ToLeft MessageBox('Повідомлення 1'); ToRight MessageBox('Повідомлення 2'); </code> **MessageWideBox** виводить повідомлення у рамці, розтягнутій по ширині <code> Show Message WideBox('Повідомлення'); </code> **Box** виводить темплейт box.html. Усі параметри необов'язкові * title - заголовок повідомлення * msg - повідомлення * wide - якщо встановлений, то рамка розтягується по ширині * css_class - css class повідомлення <code> Show Box( title => 'Заголовок', wide => 1, msg => 'Текст повідомлення всередині рамки', css_class => 'error txtpadding', ); </code> **WideBox** теж, що й Box, але параметр wide встановлений в 1 <code> Show WideBox(); </code> **Menu** Menu теж, що і MessageWideBox, але повідомлення має css class `navmenu`, що наказує виводити гіперпосилання на всю ширину блоку, одне під одним. <code> ToLeft Menu( url->a( 'Список клієнтів', a=>'users' ). url->a( 'Статистика трафіку', a=>'traf_log' ). url->a( 'Google', -base=>'http://google.com' ) ); </code> **Center** виводить інформацію відцентрованої по горизонталі <code> Show Center MessageBox('Center'); </code> Відмінність від css h_center у цьому, що дозволяє центрувати як текст. **Error** виводить повідомлення про помилку та завершує виконання скриптів <code> 1 > 2 && Error('1 > 2 !!!'); </code> **Error_** теж, що й Error, але повідомлення обробляється підпрограмою %%_(%%) <code> $lang::hello_msg = 'Здрастуйте [filtr|bold], на вашому рахунку [bold] $'; Error_($lang::hello_msg, 'адміністратор', 1000); </code> **ErrorMess** теж, що й Error, але виконання скрипту не припиняється <code> ErrorMess('Щось не так!'); Error('Точно щось не так...'); </code> ===== Pay_to_DB ===== **Pay_to_DB** створює запис у таблиці pays за вхідними параметрами: * uid - id клієнта, з яким пов'язана запис чи 0, а то й пов'язана. Необов'язковий параметр за промовчанням 0. * cash – сума, або 0, якщо платіж не фінансовий. Необов'язковий параметр за промовчанням 0. * reason - поле reason. Необов'язковий параметр. * comment – поле comment. Необов'язковий параметр. * time - timestamp платежу. Необов'язковий параметр за промовчанням поточний час. * category - категорія. Обов'язковий параметр. Повертає 1 у разі успішного запису. У параметрах запису автоматично встановлюється автор адмін або клієнт залежно від авторизованого. Також встановлюється IP. \\ Якщо запис фінансовий, то має бути виконаний у транзакції, наприклад: <code> Db->begin_work або Error($lang::err_try_again); my $rows1 = Db->do("UPDATE users SET balance=balance+(?) WHERE id=?", $money, $uid); my $rows2 = Pay_to_DB(uid=>$uid, cash=>$money, category=>1); if( $rows1 < 1 || $rows2 < 1 || !Db->commit ) { Db->rollback; Error($lang::err_try_again); } </code> Тут Db->begin_work перемикає Db на режим транзакцій. Починаючи з цього моменту, sql update/insert будуть виконуватися, але не фіксуватися в БД поки не буде виконаний Db->commit. У разі перевіряється, що обидва запити було виконано успішно, тобто. якщо хоча б один із запитів повернув менше одиниці - виконується відкат Db->rollback. Відкат гарантує, що жоден із запитів не буде зафіксовано у БД. Також він вимикає режим транзакцій. ===== Get_usr_info ===== Отримує дані клієнта щодо його id. У разі успіху повертає посилання на хеш з даними, інакше повідомлення про помилку. <code> my $ info = Get_usr_info(15); ref $info або Error $info; Show 'ПІБ клієнта з id=15: '.v::filtr($info->{fio}); </code> Підпрограма повертає як основні дані, а й додаткові поля, і навіть список ip, які належать клієнту. <code> debug('pre', $info); </code> ===== _() ===== Підпрограма, що складається з одного символу підкреслення, вставляє в заданий рядок параметри: <code> Show _('[div][p h_center][div bold h_right]', 'Текст1', 'Текст2', 'Текст3'); </code> Перетворюється на: <code> <div>Текст1</div><p class='h_center'>Текст2</p><div class='bold h_right'>Текст3</div> </code> Як видно, квадратні дужки вказують на вставку чергового параметра у поточне місце. При цьому перше слово у квадратних дужках вказує на тег. Є кілька зарезервованих слів, які не вказують на тег, наприклад, filtr - ескейпити html-спецсимволи в параметрі. trim – видаляє прогалини по краях параметра. Крім того, вертикальна характеристика дозволяє вставляти кілька керуючих послідовностей: <code> Show _('Ви ввели [filtr|trim|span bold]', 'xxx'); </code> Перетворюється на рядок «Ви ввели <span class='bold'>xxx</span>» ====== Таблиці ====== perl код <code> # Створюємо таблицю my $tbl = tbl->new(-class=>'td_wide'); # Перший рядок $tbl->add( '*', 'lll', 'комірка 1', 'комірка 2', 'комірка 3' ); # Другий рядок $tbl->add( '*', 'lll', 'комірка 1', 'комірка 2', 'комірка 3' ); # Виводимо таблицю Show $tbl->show; </code> Методом new створюється нова порожня таблиця. Вхідні параметри: <code> -class : css class таблиці -row1 : css class першого ряду -row2 : css class другого ряду </code> Параметри не є обов'язковими. Можуть бути взяті з іншого: perl код <code> my $tbl1 = tbl->new( -class=>'td_wide td_ok' ); # Class для таблиці 2 буде 'td_wide td_ok' my $tbl2 = $tb1->new(-row1=>'row5'); </code> Приклади класів для таблиць <code> td_wide : таблиця максимальної ширини fade_border : осередки відокремлюються напівпрозорими лініями pretty : якщо в таблиці буде мало рядків, то вони будуть більшими за висотою td_ok : оптимальний паддинг для осередків таблиці td_tall : високі рядки td_medium : рядки середньої висоти td_wide : широкі осередки td_narrow : вузькі осередки </code> Рядки додаються методами add (наприкінці таблиці) і ins (на початок таблиці.). Формат параметрів: * css ряду, що вставляється * рядок - карта осередків * осередок 1 * осередок 2 * ... Якщо в css буде символ зірочка - це вказівка дати ряду css з параметра -row1, після чого значення в -row1 і -row2 обміняються місцями. У такий спосіб можна організувати «зебру». Карта осередків - це рядок, який описує вирівнювання кожного осередку: <code> l : вирівнювання по лівому краю r : з правого c : по центру L : по лівому та 2 осередки об'єднуються в один R : праворуч і 2 осередки об'єднуються в одну C : по центру та 2 осередки об'єднуються в один E : по лівому та 3 осередки об'єднуються в один 3 : по центру та 3 осередки об'єднуються в один 4 : по центру та 4 осередки об'єднуються в один .. 9: по центру та 9 осередків об'єднуються в одну t : по центру та вертикальне вирівнювання top T : 2 осередки в одну, по центру та вертикальне вирівнювання top пробіл : порожній осередок </code> perl код <code> my $tbl = tbl->new( -class=>'td_wide td_ok' ); $tbl->add( '*', 'rcl', 'рівняння праворуч', 'центр', 'ліво'); $tbl->add( '*', 'rL', 'текст у 1й комірці', 'комірка 2 і 3 об'єднана в 1'); $tbl->add( '*', '3', 'текст центром і всі осередки об'єднані в одну'); Show $tbl->show; </code> Якщо будь-яка комірка буде у квадратних дужках - це відключить фільтрацію html-спецсимволів. Якщо ви відображаєте дані, надіслані клієнтом, ви не повинні відключати фільтрацію. perl код <code> $tbl->add( '*', 'rl', 'ви надіслали рядок', ses::input('str')); $tbl->add( '*', 'rl', 'поле введення', [ v::input_t(name=>'str') ])); </code> Автоматично ведеться облік рядків та стовпців таблиці. Метод rows дозволяє отримати поточну кількість рядів. Якщо при вставці рядків з'ясовується, що осередок менше ніж у попередньому, то йде автоматичне розширення останнього шляхом об'єднання з рештою: perl код <code> $tbl->add( '*', 'll', 'Здрастуйте', 'Станіслав'); осередок буде з'єднаний з останньою т.к. у попередньому рядку 2 стовпці $tbl->add( '*', 'l', 'сьогодні все ок'); # return не спрацює т.к. у таблиці 2 рядки $tbl->rows < 1 && return; </code> **Альтернативний спосіб вставки рядків** дозволяє надавати css клас персонально кожному осередку (а не тільки всьому рядку в цілому). Крім того, для кожного осередку вказується заголовок. Кожен рядок необхідно обернути у квадратні дужки: perl код <code> $tbl->add( '*', [ [ 'bold h_left', 'Заголовок 1й колонки', 'Увага' ], [ 'h_right', 'Заголовок 2й колонки', 'всім' ], ]); </code> У результаті буде вставлено рядок із двома осередками: у першому вирівнювання по лівому краю, у другій - по правому. У лівій виділений (клас bold) текст «Увага», у правій текст «усім». Коли таблиця буде виведена, то її шапці у першому осередку буде текст «Заголовок 1й колонки», у 2й - «Заголовок 2й колонки». \\ \\ ====== Package Url ====== Призначений на формування гіперпосилань. Методи <code> new : створення нового об'єкту a : рендеринг url-об'єкта в гіперпосилання post_a : рендеринг у гіперпосилання, при натисканні на яке дані будуть надіслані post-методом form : рендеринг url-об'єкта у форму url: отримання url з об'єкта redirect: редирект </code> Якщо параметр **не** починається зі знака тире – це параметр url-а: perl код <code> my $url = url->new( a=>1, b=>2, -class=>'nav', -style=>'color:#000' ); Show $url->a('Текст посилання'); </code> Буде перетворено на <a href='?a=1&b=2' class='nav' style='color:#000'>Текст посилання</a> Одне посилання можна створити на основі іншого, можна перевизначати параметри і т.д. perl код <code> my $url = url->new( a=>1, b=>2, -class=>'nav', -style=>'color:#000' ); my $ url2 = url-> new (b => 3); #?a=1&b=3 $url2->{a} = 'demo'; #?a=demo&b=3 Show $url2->a('OK', b=>4); #?a=demo&b=4 $url->{b} = undef; Show $url2->a('OK'); #?a=demo </code> У всіх параметрах ескейп html-спецсимволи. Квадратні дужки відключають це, найчастіше необхідно для тексту посилання: perl код <code> my $url = url->new(-class=>'nav'); Але краще це зробити через стиль або клас Show $url->a( [ '<b>Bold text</b>' ] ); </code> У формах порядок параметрів відрізняється від гіперпосилання, спочатку параметри, потім вміст форми: perl код <code> my $form = _('[p][p h_center][p h_center]', 'Введіть ціле позитивне число:', v::input_t(name=>'num'), v::submit('Далі') ); my $form = $Url->form( a=>'module_name', param2=>'test', $form ); </code> Параметр -ajax автоматично конвертується на -class='ajax'. При цьому JS NoDeny усі посилання, у яких присутній такий клас, робить «аяксовими» - при натисканні на такі посилання не завантажується нова сторінка, але йде http-запит на сервер, а відповідь обробляється скриптом nody.js у браузері. \\ \\ ====== Package Db ====== Призначений для роботи з базою даних. Основний метод – sql. 2 формати виклику * Db->sql(sql, параметри для плейсхолдерів) * Db->sql%%({%% параметри}) Якщо необхідна вибірка лише одного рядка: <code> my %p = Db->line(параметри); </code> Хеш %p порожній якщо * Порожня вибірка * сталася помилка (невірний sql, дисконнект БД,...) Щоб уточнити: DB->ok повертає 1, якщо не було помилок. Вибір одного рядка <code> my %p = Db->line("SELECT * FROM users WHERE id=? AND grp=?", $id, $grp); Show %p? "$p{name}, $p{fio}" : Db->ok? 'порожня вибірка' : 'внутрішня помилка'; </code> Вибірка кількох рядків <code> my $db = Db->sql("SELECT id, name FROM users WHERE field=?", $unfiltered_field); while( my %p = $db->line ) { Show "$p{id} = $p{name}<br>"; } </code> Вибір декількох рядків з іншим форматом виклику <code> my $db = Db->sql( sql => "SELECT * FROM tbl WHERE field=? AND val=?", param => [ $filed, $val ], comment => 'Вибірка номер 2', ); while( my %p = $db->line ) { ... } </code> UPDATE/INSERT <code> my $rows = Db->do("UPDATE websessions SET uid=?, role=? WHERE ses=? LIMIT 1", $id, $role, $ses); $rows>0 or Error('Помилка!'); не робіть $rows or Error() т.к. rows може = -1 </code> Виконання кількох запитів у транзакції <code> Db-> do_all ( [$sql1, $param1, $param2 ], [$sql2, $param3 ], ); </code> Перевіряється, що кожен запит торкнувся як мінімум 1 рядка. Увага! Якщо запит виконався, але не торкнувся жодного рядка (жоден збіг за умовою WHERE), то буде відкат транзакції. Додаткові методи * disconnect - розриває з'єднання з БД * connect - здійснює з'єднання з БД * begin_work - старт транзакції * commit - коміт транзакції * rollback - відкат транзакції * ok - чи був успішний останній виконаний sql * rows - рядків торкнувся останній виконаний sql * filtr - екранування небезпечних символів sql nodeny/docs/calls.pm.txt Востаннє змінено: 15/05/2023 12:46повз Method Увійти