Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
abills:docs:development:manual:ru [2018/01/14 18:12]
anton [Работа с БД]
abills:docs:development:manual:ru [2019/02/21 10:57] (текущий)
andriy [Основная часть модуля - вебинтерфейс]
Строка 29: Строка 29:
 Поскольку все ''​webinterface''​ выполняются в глобальной области видимости,​ к имени каждой функции нужно добавлять имя модуля.\\ Поскольку все ''​webinterface''​ выполняются в глобальной области видимости,​ к имени каждой функции нужно добавлять имя модуля.\\
  
-==== Основная часть - вебинтерфейс ==== +==== Основная часть ​модуля ​- вебинтерфейс ==== 
-В основном случае,​ логика вебинтерфейса проста и прозрачна - получить данные,​ обработать и вывести в каком-то виде (шаблон или таблица).+В основном случае,​ логика вебинтерфейса проста и прозрачна - получить данные,​ обработать и вывести в каком-то виде (шаблон или таблица).\\ 
 +Фреймворк неявно (через глобальную область видимости) передаёт в ''​webinterface''​ следующие переменные:​ 
 +^ Имя ^ Описание ^ 
 +|%LANG ​ |хеш-масив словаря | 
 +|%FORM ​ |хеш-масив значений переданных на страницу (GET или POST запросом) | 
 +|$html ​ |Обьект визуализации (экземпляр класса ''​Abills::​HTML''​) | 
 +|$users |Менеджер работы с пользователями (экземпляр класса ''​Users''​). **Использовать только в функциях админ. интерфейса.** | 
 +|$db    |Соединение с БД | 
 +|$admin |Менеджер работы с администраторами (экземпляр класса ''​Admins''​)| 
 +|%conf ​ |хеш-масив конфигурационного файла | 
 + 
 +Для примера рассмотрим работу с сущностью ''​entity''​ в модуле ''​Example''​\\ 
 Получить данные можно несколькими способами:​ Получить данные можно несколькими способами:​
   * Из БД (ссылка на работу с БД)   * Из БД (ссылка на работу с БД)
   * Из внешнего источника (здесь ссылка на web_request)   * Из внешнего источника (здесь ссылка на web_request)
 +  * Из файловой системы
   * Из других модулей   * Из других модулей
  
-Для примера рассмотрим работу с сущностью ''​entity''​ в модуле ''​Example''​\\+Для ​CRUD операций в ABillS принято использовать одну отдельную функцию в которой происходят следующие операции: 
 +  * Добавление новой сущности 
 +  * Редактирование ​сущности 
 +  * Удаление сущности 
 +  * Отображение списка сущностей 
 +  * Отображение сущности (совмещено с редактированием
 + 
 +Если используется ​работа с БД, то внутри файла ''​webinterface''​ инициализируется обьект менеджера работы ​с сущностями. 
 +<code perl> 
 +use Example; # Загрузить файл /​usr/​abills/​Abills/​mysql/​Example.pm 
 +my $Example = Example->​new($db,​ $admin, \%conf); # Создать объект менеджера 
 +</​code>​ 
 + 
 +В коде функция работы с сущностями будет выглядеть так: 
 +<code perl> 
 +#​********************************************************** 
 +=head2 entity_example_main() 
 + 
 +=cut 
 +#​********************************************************** 
 +sub entity_example_main{ 
 +  # Хеш для переменных шаблона обьявляется в области видимости функции 
 +  my %template_args = (); 
 +   
 +  # Флаг отображения шаблона 
 +  my $show_template = $FORM{add_form} || 0; 
 +   
 +  # Здесь используется глобальный хеш %FORM,  
 +  # который доступен в глобальной области видимости 
 +  # и включает значения,​ полученные из GET или POST запроса. 
 +  if ($FORM{add}) { 
 +    $Example->​entity_add({%FORM});​ 
 +    $show_template = !show_result($Example,​ $lang{ADDED});​ 
 +  } 
 +  elsif ($FORM{change}) { 
 +    $Example->​entity_change({%FORM});​ 
 +    show_result($Example,​ $lang{CHANGED});​ 
 +    $show_template = 1; 
 +  } 
 +  elsif ($FORM{chg}) { 
 +    my $entity_info = $Example->​entity_info($FORM{chg});​ 
 +    if (!_error_show($Entity)) { 
 +      %template_args = %{$entity_info};​ 
 +      $show_template = 1; 
 +    } 
 +  } 
 +  elsif ($FORM{del} && $FORM{COMMENTS}) { 
 +    $Example->​entity_del({ ID => $FORM{del}, COMMENTS => $FORM{COMMENTS} }); 
 +    show_result($Example,​ $lang{DELETED});​ 
 +  } 
 +   
 +  # Использование этой точки выхода 
 +  # позволяет использовать эту же функцию 
 +  # только для выполнения операции (например AJAX запросом) 
 +  return 1 if $FORM{MESSAGE_ONLY};​ 
 + 
 +  # Здесь собрана логика обработки данных для отображения шаблона ​  
 +  if ($show_template) { 
 +    # Отображение шаблона 
 +    $html->​tpl_show( 
 +      _include('example_entity''Example'), 
 +      { 
 +        %TEMPLATE_ARGS,​ 
 +        %FORM, 
 +        SUBMIT_BTN_ACTION => ($FORM{chg}) ? '​change'​ : '​add',​ 
 +        SUBMIT_BTN_NAME ​  => ($FORM{chg}) ? $lang{CHANGE} : $lang{ADD},​ 
 +      } 
 +    ); 
 +  } 
 +   
 +  # Использование этой точки выхода 
 +  # позволяет использовать эту же функцию 
 +  # для отображения шаблона изменения внутри модального окна 
 +  return 1 if ($FORM{TEMPLATE_ONLY});​ 
 +   
 +  # Использование библиотеки Abills::​ResultFormer 
 +  # для получения списка из БД (метод $Example->​entities_list($attr)) и построения таблицы (Abills::​HTML->​table($attr)) 
 +  my Abills::​HTML $table; ($table) = result_former( 
 +    { 
 +      INPUT_DATA ​     => $Example, 
 +      FUNCTION ​       => 'entities_list'
 +      BASE_FIELDS ​    => 0, 
 +      DEFAULT_FIELDS ​ => 'ID,​NAME,​VALUE'
 +      FUNCTION_FIELDS => '​change,​del',​ 
 +      SKIP_USER_TITLE => 1, 
 +      EXT_FIELDS ​     => 0, 
 +      EXT_TITLES ​     => { 
 +        id             => '#',​ 
 +        name           => $lang{NAME},​ 
 +        value          => $lang{VALUE},​ 
 +      }, 
 +      TABLE => { 
 +        width   => '​100%',​ 
 +        caption => $lang{ENTITY},​ 
 +        ID      => '​ENTITIES_TABLE',​ 
 +        EXPORT ​ => 1, 
 +        MENU    => "​$lang{ADD}:​index=$index&​add_form=1:​add"​ 
 +      }, 
 +      MAKE_ROWS ​    => 1, 
 +      SEARCH_FORMER => 1, 
 +      MODULE ​       => '​Example',​ 
 +    } 
 +  ); 
 +   
 +  # Таблицу нужно выводить отдельно 
 +  print $table->​show();​ 
 +   
 +  # Сообщаем движку,​ что функция завершилась нормально 
 +  return 1; 
 +
 +</​code>​ 
  
  
 ==== Работа с БД ==== ==== Работа с БД ====
-Все классы работы с БД наследуются от ''​dbcore''​. В таком случае в классе становятся доступны следующие методы:​\\+Все классы работы с БД наследуются от ''​dbcore''​. ​\\ 
 +В таком случае в классе становятся доступны следующие методы:​\\
 | query($query,​ $type, $attr) | выполнение запроса к БД ( В основном используется для операции ''​SELECT''​ )| | query($query,​ $type, $attr) | выполнение запроса к БД ( В основном используется для операции ''​SELECT''​ )|
 | changes($table,​ $data, $attr) | обёртка над query("​UPDATE ..."). Сравнивает данные в таблице и изменяет только поля с обновлёнными значениями. Может добавлять в системный лог записи об изменении| | changes($table,​ $data, $attr) | обёртка над query("​UPDATE ..."). Сравнивает данные в таблице и изменяет только поля с обновлёнными значениями. Может добавлять в системный лог записи об изменении|
Строка 49: Строка 174:
 Все эти методы должны вызываться в объекте с заданными полями ''​conf'',​ ''​db'',​ ''​admin''​ (''​$self->​{db}'',​ ''​$self->​{conf}'',​ ''​$self->​{admin}''​). \\ Все эти методы должны вызываться в объекте с заданными полями ''​conf'',​ ''​db'',​ ''​admin''​ (''​$self->​{db}'',​ ''​$self->​{conf}'',​ ''​$self->​{admin}''​). \\
  
-Рассмотрим работу с каждым из методов детальнее.+Конструктор в общем случае должен реализовать как минимум этот функционал 
 +<code perl> 
 +#​********************************************************** 
 +=head2 new($db, $admin, \%conf) - Constructor for Example 
 + 
 +=cut 
 +#​********************************************************** 
 +sub new{ 
 +  my ($class, $db, $admin, $CONF) = @_; 
 +  my $self = { 
 +    db    => $db, 
 +    admin => $admin, 
 +    conf  => $CONF 
 +  }; 
 + 
 +  bless($self,​ $class); 
 +  return $self; 
 +
 +</​code>​ 
 + 
 +Рассмотрим работу с каждым из унаследованных ​методов детальнее.
 <​accordion><​panel title="​**Таблица,​ которая используется в запросах**"><​code mysql> <​accordion><​panel title="​**Таблица,​ которая используется в запросах**"><​code mysql>
  
Строка 93: Строка 238:
 Использование этого ключа связано с системой шаблонов,​ по утверждённому стандарту,​ названия столбцом таблицы указываются в __lowercase__,​ а переменные шаблона указываются в __UPPERCASE__. Таким образом,​ для передачи данных из БД в шаблон,​ пришлось бы вручную переназначать ​ переменные при передаче в шаблон. Ключ ''​COLS_UPPER''​ дублирует ключи в хеше в в виде UPPERCASE, что позволяет передавать строки результата в шаблон без дополнительной логики. Использование этого ключа связано с системой шаблонов,​ по утверждённому стандарту,​ названия столбцом таблицы указываются в __lowercase__,​ а переменные шаблона указываются в __UPPERCASE__. Таким образом,​ для передачи данных из БД в шаблон,​ пришлось бы вручную переназначать ​ переменные при передаче в шаблон. Ключ ''​COLS_UPPER''​ дублирует ключи в хеше в в виде UPPERCASE, что позволяет передавать строки результата в шаблон без дополнительной логики.
  
 +
 +==== Создание базовой страницы ====
 +
 +Создаем базовую страницу сервиса
 +
 +''​cgi-bin/​hello.cgi''​
 +  ​
 +<​code>​
 +#​!/​usr/​bin/​perl
 +=head1 NAME
 +
 + ​Hello ​ world
 +
 +=cut
 +
 +use strict;
 +use warnings;
 +
 +# Включение нужных путей
 +BEGIN {
 +  our $libpath = '​../';​
 +  my $sql_type = '​mysql';​
 +  unshift(@INC,​
 +    $libpath . "​Abills/​$sql_type/",​
 +    $libpath . "​Abills/​modules/",​
 +    $libpath . '/​lib/',​
 +    $libpath . '/​Abills/',​
 +    $libpath
 +  );
 +}
 +
 +#​Модуль конфигурации
 +use Conf;
 +our (
 +  $libpath,
 +  %conf,
 +  %lang,
 +  $base_dir,
 +);
 +
 +# конфигурационный файл
 +do "​../​libexec/​config.pl";​
 +
 +# HTML визуализация
 +use Abills::​HTML;​
 +my $html = Abills::​HTML->​new(
 +  {
 +    IMG_PATH => '​img/',​
 +    NO_PRINT => 1,
 +    CONF     => \%conf,
 +    CHARSET ​ => $conf{default_charset},​
 +  }
 +);
 +
 +# Подключение базы
 +use Abills::​SQL;​
 +my $db = Abills::​SQL->​connect($conf{dbtype},​ $conf{dbhost},​ $conf{dbname},​ $conf{dbuser},​ $conf{dbpasswd},​ {
 +  CHARSET => ($conf{dbcharset}) ? $conf{dbcharset} : undef
 +});
 +
 +# Включение базовых словарей
 +if($html->​{language} ne '​english'​) {
 +  do $libpath . "/​language/​english.pl";​
 +}
 +
 +if(-f $libpath . "/​language/​$html->​{language}.pl"​) {
 +  do $libpath."/​language/​$html->​{language}.pl";​
 +}
 +
 +# Подключение модуля работы с шаблонами ​
 +require Abills::​Templates;​
 +
 +# Включение конфигурационного файла
 +Conf->​new($db,​ undef, \%conf);
 +
 +$html->​{METATAGS} = templates('​metatags_client'​);​
 +
 +print $html->​header();​
 +
 +# Диалоговое окно приветсвия
 +print $html->​message('​info',​ $lang{INFO},​ "Hello world\nSystem name '​$conf{WEB_TITLE}'"​);​
 +
 +1;
 +</​code>​