В любой модуль, кроме авторизации, можно попасть лишь будучи авторизованным. Авторизация бывает доверенной и недоверенной. Если источник авторизации надежный, например, авторизация по логину и паролю, он устанавливает параметр trust в 1. Опасные функции следует разрешать только при доверенном соединении:
$ses::auth->{trust} or Error('Соединение не доверенное. Необходимо перелогиниться');
В клиентскую статистику может попасть не только клиент, но и администратор от его имени, поэтому в некоторых случаях желательно выводить разную информацию для админа и клиента, а также фиксировать, что именно администратор выполнил действие:
if( 1 + 1 > 3 ) { Error( Adm->id? 'Паника! Perl неправильно считает' : 'Сервис временно недоступен'); } # Пополним счет клиента, при этом Pay_to_DB сама проставит автора Pay_to_DB(uid=>$uid, cash=>10, category=>1);
Получить параметры, переданные через браузер, можно с помощью ses::input:
if( ses::input('a') eq 'test' && ses::input_exists('b') ) { # Условие сработает т.к. в url a=test и параметр b присутствует # Параметр uid на всякий случай принудительно приведем к целому числу my $uid = ses::input_int('uid'); $uid or Error('Введите целое число, не равное нулю'); }
Хеш всех переданных параметров хранится в $ses::input_orig:
# Если параметр yes не существует либо не установлен, # отредиректимся сами на себя и пошлем все параметры + установим yes ses::input('yes') or url->redirect( { %$ses::input_orig, yes=>1 } );
Существует альтернативный способ передачи параметров - данные записываются в базу данных в таблицу 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:
$Url->redirect(a=>'main', uid=>15);
В данном случае произойдет запись {a=>'main', uid=>15} в webses_data, после чего произойдет переход http:://xxx/?_unikey=yyyyyy. Здесь yyyyyy - ключ к данным, записанным в таблицу.
Раз уж мы заговорили о редиректе, то отметим 2 полезных его параметра -made и -error. Первый предназначен для того, чтобы вывести сообщение вверху страницы после редиректа, при этом если будет установлен -error, то красным цветом:
$Url->redirect(a=>'main', -error=>1, -made=>'Ошибочная операция. Редиректимся на титульную страницу');
ToLeft 'Текст слева';
ToLeft MessageBox('Сообщение 1'); ToRight MessageBox('Сообщение 2');
Show MessageWideBox('Сообщение');
Show Box( title => 'Заголовок', wide => 1, msg => 'Текст сообщения внутри рамки', css_class => 'error txtpadding', );
Show WideBox();
ToLeft Menu( url->a( 'Список клиентов', a=>'users' ). url->a( 'Статистика трафика', a=>'traf_log' ). url->a( 'Google', -base=>'http://google.com' ) );
Show Center MessageBox('Center');
1 > 2 && Error('1 > 2 !!!');
$lang::hello_msg = 'Здравствуйте [filtr|bold], на вашем счету [bold] $'; Error_($lang::hello_msg, 'администратор', 1000);
ErrorMess('Что-то не так!'); Error('Точно что-то не так...');
Db->begin_work or 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); }
my $info = Get_usr_info(15); ref $info or Error $info; Show 'ФИО клиента с id=15: '.v::filtr($info->{fio});
debug('pre', $info);
Show _('[div][p h_center][div bold h_right]', 'Текст1', 'Текст2', 'Текст3');
<div>Текст1</div><p class='h_center'>Текст2</p><div class='bold h_right'>Текст3</div>
Show _('Вы ввели [filtr|trim|span bold]', ' xxx ');
# Создаем таблицу my $tbl = tbl->new( -class=>'td_wide' ); # Первая строка $tbl->add( '*', 'lll', 'ячейка 1', 'ячейка 2', 'ячейка 3' ); # Вторая строка $tbl->add( '*', 'lll', 'ячейка 1', 'ячейка 2', 'ячейка 3' ); # Выводим таблицу Show $tbl->show;
Методом new создается новая пустая таблица. Входные параметры:
-class : css class таблицы -row1 : css class первого ряда -row2 : css class второго ряда
Параметры не обязательны. Могут быть взяты из другой:
my $tbl1 = tbl->new( -class=>'td_wide td_ok' ); # Class для таблицы 2 будет 'td_wide td_ok' my $tbl2 = $tb1->new( -row1=>'row5' );
td_wide : таблица максимальной ширины fade_border : ячейки отделяются полупрозрачными линиями pretty : если в таблице будет мало строк, то они будут больше по высоте td_ok : оптимальный паддинг для ячеек таблицы td_tall : высокие строки td_medium : строки средней высоты td_wide : широкие ячейки td_narrow : узкие ячейки
Строки добавляются методами add (в конец таблицы) и ins (в начало таблицы.). Формат параметров:
Если в css будет присутствовать символ звездочка - это указание дать ряду css из параметра -row1, после чего значения в -row1 и -row2 обменяются местами. Таким образом можно организовать «зебру».
Карта ячеек - это строка, которая описывает выравнивание каждой ячейки:
l : выравнивание по левому краю r : по правому c : по центру L : по левому и 2 ячейки объединяются в одну R : по правому и 2 ячейки объединяются в одну C : по центру и 2 ячейки объединяются в одну E : по левому и 3 ячейки объединяются в одну 3 : по центру и 3 ячейки объединяются в одну 4 : по центру и 4 ячейки объединяются в одну .. 9 : по центру и 9 ячеек объединяются в одну t : по центру и вертикальное выравнивание top T : 2 ячейки в одну, по центру и вертикальное выравнивание top пробел : пустая ячейка
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;
Если какая-либо ячейка будет в квадратных скобках - это отключит фильтрацию html-спецсимволов. Если вы отображаете данные, посланные клиентом, вы не должны отключать фильтрацию.
$tbl->add( '*', 'rl', 'вы прислали строку', ses::input('str')); $tbl->add( '*', 'rl', 'поле ввода', [ v::input_t(name=>'str') ]);
Автоматически ведется учет строк и столбцов таблицы. Метод rows позволяет получить текущее количество рядов. Если при вставке строк выясняется, что ячеек меньше чем в предыдущей, то идет автоматическое расширение последней путем объединения с оставшимися:
$tbl->add( '*', 'll', 'Здравствуйте', 'Станислав'); # ячейка будет объеденена с последней т.к. в предыдущей строке 2 столбца $tbl->add( '*', 'l', 'сегодня все ок'); # return не сработает т.к. в таблице 2 строки $tbl->rows < 1 && return;
Альтернативный способ вставки строк позволяет присваивать css класс персонально каждой ячейке (а не только всей строке в целом). Кроме того, для каждой ячейки указывается заголовок. Каждую строку необходимо обернуть в квадратные скобки:
$tbl->add( '*', [ [ 'bold h_left', 'Заголовок 1й колонки', 'Внимание' ], [ 'h_right', 'Заголовок 2й колонки', 'всем' ], ]);
В результате будет вставлена строка с двумя ячейками: в первой выравнивание по левому краю, во второй - по правому. В левой выделенный (класс bold) текст «Внимание», в правой текст «всем». Когда таблица будет выведена, то в ее шапке в первой ячейке будет текст «Заголовок 1й колонки», во 2й - «Заголовок 2й колонки».
Предназначен для формирования гиперссылок.
new : создание нового объекта a : рендеринг url-объекта в гиперрсылку post_a : рендеринг в гипперссылку, при нажатии на которую данные будут отправленны post-методом form : рендеринг url-объекта в форму url : получение url из объекта redirect: редирект
Если параметр не начинается со знака тире - это параметр url-а:
my $url = url->new( a=>1, b=>2, -class=>'nav', -style=>'color:#000' ); Show $url->a('Текст ссылки');
Будет преобразовано в <a href='?a=1&b=2' class='nav' style='color:#000'>Текст ссылки</a>
Одну ссылку можно создать на основе другой, можно переопределять параметры и т.д.:
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
Во всех параметрах эскейпятся html-спецсимволы. Квадратные скобки отключают это, чаще всего необходимо для текста ссылки:
my $url = url->new( -class=>'nav' ); # Но лучше это сделать через стиль или класс Show $url->a( [ '<b>Bold text</b>' ] );
В формах порядок параметров отличается от гиперрсылки, сначала параметры, затем содержимое формы:
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 );
Параметр -ajax автоматически конвертируется в -class='ajax'. При этом JS NoDeny все ссылки, у которых присутствует такой класс, делает «аяксовыми» - при клике на такие ссылки не загружается новая страница, но идет http-запрос на сервер, а ответ обрабатывается скриптом nody.js в браузере.
Предназначен для работы с базой данных. Основной метод - sql.
Если необходима выборка только одной строки:
my %p = Db->line( параметры );
Чтобы уточнить: Db->ok возвращает 1, если не было ошибок.
my %p = Db->line("SELECT * FROM users WHERE id=? AND grp=?", $id, $grp); Show %p? "$p{name}, $p{fio}" : Db->ok? 'пустая выборка' : 'внутренняя ошибка';
my $db = Db->sql("SELECT id, name FROM users WHERE field=?", $unfiltered_field); while( my %p = $db->line ) { Show "$p{id} = $p{name}<br>"; }
my $db = Db->sql( sql => "SELECT * FROM tbl WHERE field=? AND val=?", param => [ $filed, $val ], comment => 'Выборка номер 2', ); while( my %p = $db->line ) { ... }
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
Db->do_all( [$sql1, $param1, $param2 ], [$sql2, $param3 ], );
Проверяется, что каждый запрос затронул как минимум 1 строку. Внимание! Если запрос выполнился, но не затронул ни одну строку (ни одного совпадения по условию WHERE), то будет откат транзакции.