![]() |
Биллинговая система NoDeny. Программирование плагинов клиентской статистики. |
NoDeny дает возможность самостоятельно нарастить функционал клиентской статистики с помощью плагинов. Если вы уверенно программируете на perl, можете взяться за работу, предварительно изучив следующее:
Клиентская статистика предоставляется скриптом stat.pl, который загружает необходимый плагин и выполняет его. Скрипт существует в двух абсолютно одинаковых экземплярах: http://..../cgi-bin/stat.pl и http://..../cgi-bin/adm/stat.pl - обусловлнено тем, что папка adm является административной и запаролена, т.е клиенты не имеют к ней доступ, поэтому получают статистику через /cgi-bin/stat.pl. С другой стороны, у администратора должна быть возможность посмотреть «глазами клиента» на его статистику, что он и делает через /cgi-bin/adm/stat.pl.
В задачи скрипта stat.pl входит: проверка авторизации, подготовка данных для плагинов, запуск плагина.
Плагины реализованы в виде файлов, имена которых начинаются с заглавной латинской буквы S. Это условие не является обязательным, но рекомендуемым для соблюдения стиля. Соблюдение стиля в разных аспектах NoDeny ведет к логичности в управлении и понимании. Имя файла должно иметь расширение pl, это обязательное условие.
Каждый плагин имеет свой уникальный номер, через который клиент его запускает. Уникальность имени и номера плагина желательно согласовывать с автором для исключения пересечения с плагинами других разработчиков.
Данные о плагине содержатся в реестре плагинов - в файле plugin_reestr.cfg. Каждая строчка файла описывает параметры плагина: имя файла, уникальный номер плагина, название плагина, разрешить ли доступ к плагину только администратору и некоторые другие данные, которые будут описаны ниже. В самом реестре даны комментарии по полям.
Каким образом скрипту stat.pl сообщается какой плагин необходимо запустить? Для этого в запросе, переданным через браузер, в переменной a указывается уникальный код плагина, например:
http://.../stat.pl?a=102
что указывает выполнить плагин с номером 102. Если переменная a не будет
определена, то будет запущен плагин с кодом 101 - отображена главная страница статистики.Перед тем как начать программировать плагины, изучите скрипт calls.pl - в нем содержится много полезных подпрограмм.
Что должно быть результатом выполнения плагина?
Существует глобальная переменная $OUT, которая является фактически html-страницей, которая будет возвращена клиенту. Код:
$OUT.='Привет!'
Добавит к формирующейся html-странице текст «Привет!». После того, как плагин завершит свою
работу (выполнит return в скрипт stat.pl), stat.pl закончит формирование html-страницы -
закроет открытые теги, после чего пошлет страницу в бразуер клиенту.Последние действия в виде кода:
$OUT.=$EOUT;
&Exit;
Здесь $EOUT - переменная, содержащая список закрывающих тегов, а &Exit - подпрограмма из calls.pl,
которая «приклеивает» заголовок к $OUT, отсылает все клиенту в браузер и выполняет exit.&Exit;
Нормальное завершение плагина - это return в stat.pl, однако в случае, если плагин фиксирует проблему или ошибочное действие, наилучшим вариантом будет запуск подпрограммы Error, которая выведет сообщение об ошибке и сделает &Exit:
&Error('Ошибка! Нет связи с ФБР!',$EOUT) unless &Connect_FBR;
- обратите внимание на присутствие $EOUT вторым параметром в &Error. Если
заглянуть в calls.pl и изучить описание к &Error, то станет понятно, что
2й параметр добавляется к $OUT сразу после вывода ошибки.Изучите глобальные переменные, доступные внутри плагина:
- %Adm
- $day_now
- $Er_Mess_for_Client
- %F
- $id
- $Mid
- $nAlias
- $OUTLEFT
- $p
- $pm
- $RealIp
- $scrpt
- $start
- $Sel_id
- $t
- $ut
- %U
- $V
Перечисленные переменные модифицировать не рекомендуется.
%Adm - хеш данных администратора, просматривающего статистику.
Поскольку статистику обычно просматривает не администратор, а клиент, то в таком случае
хеш содержит всего одно значение: $Adm{id}=0. Создавая плагины вы всегда должны
помнить о том, что он может быть запущен как администратором так и клиентом, поэтому
хорошим стилем, а также условием безопасности, является пометка кем было
осуществлено действие клиентом или администратором.
$Adm{id} - id администратора, либо 0, если статистику просматривает клиент.
$Adm{office} - отдел администратора.
$Adm{login} - логин администратора.
$Adm{id} - id администратора, либо 0, если статистику просматривает клиент.
$Adm{office} - отдел администратора.
$Adm{login} - логин администратора.
%F - хеш, содержащий данные, которые клиент послал через браузер.
Например, клиент послал запрос:
$F{a}=101
$F{day}=10
Если в запросе одна и таже переменная встречается больше одного раза, то за основу берется последнее значение, например:
Приведет к результату: $F{a}=102
Эта особенность применяется, когда необходимо изменить уже существующий запрос. Например, глобальная переменная $scrpt содержит url текущей страницы вместе с переданными данными, скажем:
мы хотим сформировать ссылку на страницу для отображения статистики не на 10 февраля, а на 11 марта:
http://.../stat.pl?a=101&day=10
Хеш %F будет заполнен такими значениями:$F{a}=101
$F{day}=10
Если в запросе одна и таже переменная встречается больше одного раза, то за основу берется последнее значение, например:
http://.../stat.pl?a=101&a=102
Приведет к результату: $F{a}=102
Эта особенность применяется, когда необходимо изменить уже существующий запрос. Например, глобальная переменная $scrpt содержит url текущей страницы вместе с переданными данными, скажем:
$scrpt = 'stat.pl?pp=...&a=101&day=10&mon=2&year=2008'
мы хотим сформировать ссылку на страницу для отображения статистики не на 10 февраля, а на 11 марта:
&ahref("$scrpt&day=11&mon=3",'показать статистику');
$RealIp - ip с которого в данный момент просматривается статистика.
Обратите внимание, что это не ip клиентской записи, это ip с которого произведен "заход"
в клиентскую статистику.
$start - номер отображаемой страницы, когда система выводит фрагмент таблицы
(определенную страницу). Найдите подпрограмму &Show_navigate_list в каком-нибудь плагине,
чтобы понять где и как используется $start.
$Sel_id используется тогда, когда у клиента несколько учетных записей и
статистика может выводиться отдельно для каждой учетной записи либо же суммарная для всех.
Например, статистику трафика можно показать для основной записи либо же для алиасной, либо же
суммарную. В переменной $Sel_id содержится список id, разделенных запятыми, для которых клиент запросил
статистику.
$OUT.=$For_U? "Запрошен вывод телефона для $For_U" : 'Запрошен вывод телефонов всех записей клиента';
$sth=&sql("SELECT telefon FROM users WHERE id IN ($Sel_id)");
$sth=&sql("SELECT telefon FROM users WHERE id IN ($Sel_id)");
$Er_Mess_for_Client - сообщение «Данные недоступны -
ведутся технические работы на сервере.». Это «отмазка» для клиентов, когда произошла
критическая ошибка, которую нельзя сообщать клиенту, администратору же ошибка выводится - смотри описание
к переменной $V.
$day_now
$day_now - текущий день $mon_now - текущий месяц (1..12) $year_now - текущий год (от 1970!)
$p - ссылка на выборку из таблицы БД для текущей клиентской записи
$OUT.='Квартира клиента: '.$p->{room};
$pm - ссылка на выборку для основной записи клиента. Если просматривается
основная запись, то $p и $pm указывают на одну и туже структуру данных.
$Mid - id основной записи клиента. Пример:
$h=&sql_select_line($dbh,"SELECT COUNT(mid) FROM pays WHERE mid=$Mid AND type=30');
$OUT.='Клиент отправил/получил '.$h->{'COUNT(mid)'}.' сообщений за все время сущестрования его учетной записи';
Обратите внимание - у клиента может быть несколько учетных записей (алиасов). Клиентстая статистика
может просматриваться от имени алиаса. Поэтому чтобы отобразить некоторые данные, которые существуют только
для основной записи (к примеру платежи), необходимо использовать $Mid.
$OUT.='Клиент отправил/получил '.$h->{'COUNT(mid)'}.' сообщений за все время сущестрования его учетной записи';
$id - id текущей записи. Если просматривается основная запись, то $Mid=$id
%U - данные всех учетных записей клиента.
Важно.
Не забывайте о безопасности, а именно о фильтрации спецсимволов в непроверенных данных, в противном случае злоумышленник сможет повредить/получить данные из БД путем посылки некорректных данных. Не исключайте, что злоумышленником может быть и ненадежный работник. Учтите, в данных таблиц базы данных содержатся нефильтрованные значения. Например, допускается фамилия <b>Иванов</b>. Поэтому при выводе данные в виде html всегда применяйте фильтр &Filtr_out, а при выполнении sql-запроса &Filtr_mysql. Это разные фильтры!
$U{$id}{name} - логин $U{$id}{ip} - ip $U{$id}{fio} - фио $U{$id}{state} - состояние записи заблокирована/не заблокирована $U{$id}{o_name} - логин с отфильтрованными спецсимволами html $U{$id}{m_name} - логин с отфильтрованными спецсимволами mysql $U{$id}{o_fio} - фио с отфильтрованными спецсимволами html $U{$id}{m_fio} - фио с отфильтрованными спецсимволами mysqlПример:
$OUT.='Логин основной записи: '.$U{$Mid}{o_name};
Важно.
Не забывайте о безопасности, а именно о фильтрации спецсимволов в непроверенных данных, в противном случае злоумышленник сможет повредить/получить данные из БД путем посылки некорректных данных. Не исключайте, что злоумышленником может быть и ненадежный работник. Учтите, в данных таблиц базы данных содержатся нефильтрованные значения. Например, допускается фамилия <b>Иванов</b>. Поэтому при выводе данные в виде html всегда применяйте фильтр &Filtr_out, а при выполнении sql-запроса &Filtr_mysql. Это разные фильтры!
$OUT.='В переменной privet вы прислали: '.&Filtr_out($F{privet});
$nAlias - количество учетных записей клиента. Если нет
алиасов, то = 1.
$OUTLEFT - всеб что будет добавлено к этой переменной,
будет выведено в левую колонку клиентской статистики. Аналогично как все, что добавляется
в $OUT - выводится в правую колонку. Однако, есть нюанс. В левую колонку можно
добавлять данные строго до выполнения основного кода плагина, имеется ввиду
подпрограмма, которая описывается в реестре.
Чтобы было понятней, необходимо описать детальнее процесс запуска плагина:
1) stat.pl производит авторизацию.
2) stat.pl получает данные клиента.
3) stat.pl формирует меню плагинов (левую колонку статистики). В этот момент происходит импортирование плагина. Т.е плагин загружается, но подпрограмма, указанная в реестре, не выполняется. Выполняется лишь код, оформленный вне подпрограмм плагина. В этом коде и предусматривается обновление $OUTLEFT. Смотрите Sdemo.pl для примера.
4) stat.pl завершает формирование левой колонки, начинает формирование правой.
5) выполняется заданная подпрограмма плагина.
Чтобы было понятней, необходимо описать детальнее процесс запуска плагина:
1) stat.pl производит авторизацию.
2) stat.pl получает данные клиента.
3) stat.pl формирует меню плагинов (левую колонку статистики). В этот момент происходит импортирование плагина. Т.е плагин загружается, но подпрограмма, указанная в реестре, не выполняется. Выполняется лишь код, оформленный вне подпрограмм плагина. В этом коде и предусматривается обновление $OUTLEFT. Смотрите Sdemo.pl для примера.
4) stat.pl завершает формирование левой колонки, начинает формирование правой.
5) выполняется заданная подпрограмма плагина.
$scrpt - url текущей страницы со ссылкой на текущий плагин
(с установленным уникальным номером плагина a).
&ahref($scrpt,'Запустить текущий плагин без параметров');
&ahref("$scrpt&a=101",'Титульная страница статистики');
$t - время на сервере основной БД. Это время принято за основу,
поскольку в системе с большим количеством серверов могут быть значительные расхождения
во времени. Во всех расчетах применяйте переменную $t. Для записи в БД используйте значение
unix_timestamp()
&sql_do($dbh,"INSERT INTO pays SET mid=$Mid,type=30,coment='Привет!',time=unix_timestamp()");
$ut - строка 'unix_timestamp()'
$V - если установлена, то означает, что статистику просматривает
не клиент, а администратор. Предназначено для того, чтобы администратору сообщать более
детальные сообщения об ошибках.
Когда переменная $V установлена, то содержит такое сообщение:
«Вы в режиме администрирования, поэтому вам видны более детальные описания ошибок:»
Таким образом, если в плагине ввести следующую строку:
Администратору же:
Когда переменная $V установлена, то содержит такое сообщение:
«Вы в режиме администрирования, поэтому вам видны более детальные описания ошибок:»
Таким образом, если в плагине ввести следующую строку:
&Error($V? "$V повреждение данных!" : 'Временная ошибка. Повторите запрос позже');
То при запуске плагина клиентом, ему будет показано сообщение:Временная ошибка. Повторите запрос позже
Администратору же:
Вы в режиме администрирования, поэтому вам видны более детальные описания ошибок:
повреждение данных!
повреждение данных!