Мануал по работе с фреймворком ABillS
Форматирование кода
- Для отступов не использовать табуляций, только двойные пробелы
Форматирование if else:
if (expr) { ... } else { ... }
Однострочные или-выражения
Всегда выражения берутся в скобки
$result = ($total_users == 1) ? "Ok" : "Fail"; print "test" if ($test == 1);
- Для удобства форматирования кода можно воспользоваться утилитой perltidy
https://support.abills.net.ua/perltidy.cgi
Переменные
Переменные указываются строчными буками
$test, @devices, %switch
Объекты указываются с заглавной
$Test = Test->new();
Массивы указываются в множественном числе
my @devices = (); my @users = ();
Хеши в единственном
%status_list = (); $status_list{disable}=1;
Общий шаблон функций
#********************************************************** =head2 test_function($attr) - Test function Arguments: $attr - Extra attributes TEXT - Some text Returns: TRUE or FALSE Example: test_function({ TEXT => 'Some text' }); =cut #********************************************************** sub test_function { my ($attr) = @_; print "Hello world!"; return 1; }
Рекомендации:
- Отделяйте шапки функций звёздочками (58 штук).
- Не игнорируйте создание комментариев перед началом функции.
- Называйте функции строчными буквами с разделением нижним подчёркиванием.
По умолчанию, в случае успешного выполнения функция должна возвращать 1, в случае ошибки - 0.
Минимизируйте использование глобальных переменных в функциях.
Дата обновления в шапке модуля
Дату обновления модуля следует указывать в шапке модуля (в начале файла) в формате YYYYMMDD.
Пример:
=head1 Cdata C-data MODEL: epon FD1104SN ... DATE: 20190704 UPDATE: 20210324 =cut
DATE - дата создания модуля
UPDATE - дата обновления модуля
Указывать дату правильно важно для коммерческих модулей, так как скрипт обновления update.sh ожидает увидеть дату в этом формате.
Можно ли использовать HTML в коде?
Ни в коем случае не используйте HTML в коде управляющей модели, вместо этого используйте объекты Abills::HTML или шаблоны.
Дополнительные модули
Загрузка дополнительных модулей Perl осуществляется командой
load_pmodule('Simple::XML');
(Библиотека Misc.pm
)
С проверкой ошибок код выглядит так:
my $loaded_imager_error = load_pmodule( "Imager", { RETURN => 1 } ); if ( $loaded_imager_error ) { print $loaded_imager_error; return 0; }
Дополнительные модули с автоустановкой
Загрузка дополнительных модулей Perl с автоустановкой осуществляется командой
load_perl_module('SQL::Translator');
(Библиотека PModules.pm
)
Поиск в полях
Для удобства поиска было разработано несколько разделителей.
Для цифровых полей
Разделитель запятая (,) обозначает AND.
Пример: искать значения поля 56 и 66
56,66
Разделитель точка с запятой (;) обозначает OR.
Пример: искать значения поля 56 или 66
56;66
Тестирование
Для тестирования системы существует каталог с тестами abills/t.
make
Жесткий тест работоспособности, никогда его не выполняйте на рабочей системе, чревато пропажей данных
perl web.t brutal
тестирование синтаксиса и стресс-тест веб-приложений
НЕ ИСПОЛЬЗОВАТЬ НА ПРОДАКШН СИСТЕМЕ
Тест проверки авторизации и аккаунтинга
t/Aaa.t
Проверка DHCP авторизации используя приготовленный RAD PAIRS пакет dhcp.discover
perl Aaa.t dhcp_test dhcp.discovery
Тестирование абон. платы тарифного плана
perl Tariffs.t FILENAME=tp_test1.tp
FILENAME - файл с описанием тарифного плана и параметров абонента.
Для задания логина и пароля авторизации используется файл t/.test
login:password
В системе также есть специальный скрипт запуска выделенных тестов, которые хранятся в отдельных каталогах: Запуск тестов для модуля или папки
Создание демона
use Abills::Base; use Abills::Server; my $ARGV = parse_arguments(\@ARGV); # Демонизация и ведение лога if (defined($ARGV->{'-d'})) { my $pid_file = daemonize(); #ведение лога #$Log->log_print('LOG_EMERG', '', "$prog_name Daemonize... $pid_file"); } # Остановка процесса elsif (defined($ARGV->{stop})) { stop_server(); exit; } # Проверка, не запущен ли уже elsif (make_pid() == 1) { exit; } # Таймаут между запусками 100 секунд my $UPDATE_TIME=100; while (1) { check_activity({ ALL => ($ARGV->{RECONFIG_PERIOD}) ? undef : $all }); sleep $UPDATE_TIME;
Языковые маркеры
Сохраняются в глобальном хеше %lang
.
Пример:
$lang{LANG_MARKER} = 'Языковой маркер';
Названия маркеров обязательно писать заглавными буквами.
Отображение в шаблонах:
_{LANG_MARKER}_
Переменные внутри lang
$lang{LANG_MARKER_WITH_VARS} = 'У абонента минус %DEPOSIT%';
И использовать функцию:
use Abills::Base qw(vars2lang); vars2lang($lang{LANG_MARKER_WITH_VARS}, { DEPOSIT => '5' });
Но, конечно, вы можете использовать любой string с такой разметкой.
JSON тестирование
Для того, чтобы протестировать функцию:
- Создайте тест в /usr/abills/t
Подключите JSON.t
require "./JSON.t";
Создайте JSON, заполнив его. API_KEY - ключ API текущего администратора
my @test_list = ( { name => 'InfoFields', params => { qindex => 96, API_KEY => '1523615231263123', json => 1 }, result => '', valid_json => 1, schema => { } } );
Передайте данные в функцию json_test
json_test( \@test_list, { TEST_NAME => 'info_fields_new test' });
Выполните ваш тест, запустив программу
# prove -v <название теста>.t
String Eval
Когда нужно загрузить динамически модуль необходимо его загрузить следующим образом
my $module = 'Example'; eval "use $module";
Но настоятельно не рекомендуется это делать в Perl. Потому нужно использовать следующий вариант
my $module_name = 'Example'; eval { my $module = "$module_name.pm"; require $module; $module->import(); 1; };
Если модуль имеет назву с названием директории пример
Module::Example
Тогда нужно получить последнее слово модуля, это его название
my $module_full_name = 'Module::Example'; my ($module_name) = $module_full_name =~ /(\w+)$/; eval { my $module = "$module_name.pm"; require $module; $module->import(); 1; };
Конфигурационные переменные
Здесь описаны правила при заполнении конфигурационных переменных.
- Если ваша переменная должна иметь изначальное значение (fallback), то нужно её добавить в функцию _fill_config_defaults.