я хотел бы на cpan.org может модуль сделать
прокомментируйте как написано, нормально? кто как реализовывал?
вот сам класс
Код: Выделить всё
package MyApp::Model::ExtraDBI;
use strict;
use warnings;
use base qw( Catalyst::Model Class::Accessor);
use NEXT;
use HTML::Entities::Numbered;
__PACKAGE__->mk_accessors(qw/bad_fields_type all_fields_type/); # вместо $f->bad_fields_type('arrey'); --> $self->bad_fields_type eq 'arrey'
# удобно когда много гемороя, в данном случае можно без него
sub new { # наследуем конструктор
my ( $self, $c ) = @_;
$self = $self->NEXT::new(@_);
}
sub no_sql { # метод если есть, то не вставляется в SQL хэш
my $self = shift;
$self->{no_sql} = 1;
return $self;
}
sub no_bad { не вставляется в массив в которой элемент-ошибка
my $self = shift;
$self->{no_bad} = 1;
return $self;
}
####
# Add out fields
###
sub _add_bad_fields {
my ($self) = @_;
if ( $self->{no_bad} == 1 ) {
$self->{no_bad} = undef;
return;
}
# куда заносить в массив или в хэш
if ( $self->bad_fields_type eq 'arrey' ) {
if ( !$self->{bad_arrey_out} ) {
$self->{bad_arrey_out} = []; # массив
}
push @{ $self->{bad_arrey_out} },
$self->{key}; # is $self->fails_type arrey
}
if ( $self->bad_fields_type eq 'hash' ) {
$self->{bad_hash_out}->{ $self->{key} } =
$self->{value}; # $self->fails_type HASH key = faild, value = name
}
}
# добавляется в другой массив или в хэш все элементы
# которые идут в SQL или в форму для возврата
sub _add_all_fields {
my ($self) = @_;
if ( $self->{no_sql} == 1 ) {
$self->{no_sql} = undef;
return;
}
if ( $self->all_fields_type eq 'arrey' ) {
if ( !@{ $self->{all_arrey_out} } ) {
$self->{all_arrey_out} = [];
}
push @{ $self->{all_arrey_out} },
$self->{key}; # is $self->fails_type arrey
}
if ( $self->all_fields_type eq 'hash' ) {
$self->{all_hash_out}->{ $self->{key} } =
$self->{value}; # $self->fails_type HASH key = faild, value = name
}
}
####
# Clean text, remove bad tag, etc
###
# приватные методы _подчеркивание
sub _del_blanks_end_began { # пробелы с начале и в конце
my $self = shift;
$self->{value} =~ s/^\s+//;
$self->{value} =~ s/\s+$//;
return $self;
}
sub _cleaning { # сносить оспасный теги
my $self = shift;
$self->{value} =~ s!\0!!g;
$self->{value} =~ s|&|;|g;
$self->{value} =~ s|<!--||g;
$self->{value} =~ s|-->||g;
$self->{value} =~ s|<script||ig;
$self->{value} =~ s|>||g;
$self->{value} =~ s|<||g;
$self->{value} =~ s|"||g;
$self->{value} =~ s| | |g;
$self->{value} =~ s!\|!|!g;
$self->{value} =~ s|\n||g;
$self->{value} =~ s|\$||g;
$self->{value} =~ s|\r||g;
$self->{value} =~ s|\_\_(.+?)\_\_||g;
$self->{value} =~ s|\\||g;
$self->{value} =~ s|\'||g;
$self->{value} =~ s|!||g;
return $self;
}
# экранируються тэги модулем
sub _clean_html {
my $self = shift;
$self->{value} = name2decimal( $self->{value} );
return $self;
}
####
# Valid fields
###
sub head_text {
my $self = shift;
$self->{key} = shift; # первый элемент
$self->{value} = shift; # второй элемент
$self->_del_blanks_end_began;
$self->_cleaning;
$self->_add_all_fields();
return $self->{value} if ( defined wantarray ); # wantarray для ттого тчобы определить если ли элемент
#который ждет получить какие-то значение $bla = $bla->bla;
# то есть если написано так $bla->bla->bla2 , что чтобы возвратить объект второму методу bla2
}
sub valid_id {
my $self = shift;
$self->{key} = shift;
$self->{value} = shift;
$self->_del_blanks_end_began();
$self->_add_all_fields();
if ( !$self->{value} =~ /^\d+$/ ) { # цифра
$self->_add_bad_fields();
$self->{value} = undef;
}
return $self->{value} if ( defined wantarray );
}
sub int_check {
my $self = shift;
$self->{key} = shift;
$self->{value} = shift;
$self->_del_blanks_end_began();
$self->{value} = $self->{value} eq 'on' ? '1' : '0';
$self->_add_all_fields();
return $self->{value} if ( defined wantarray );
}
sub one_die {
my $self = shift;
$self->{key} = shift;
$self->{value} = shift;
$self->_del_blanks_end_began();
$self->_add_all_fields();
if ( !$self->{value} == 1 ) {
$self->_add_bad_fields();
$self->{value} = undef;
}
return $self->{value} if ( defined wantarray );
}
sub zero_die {
my $self = shift;
$self->{key} = shift;
$self->{value} = shift;
$self->_del_blanks_end_began();
$self->_add_all_fields();
if ( !$self->{value} == 0 ) {
$self->_add_bad_fields();
$self->{value} = undef;
}
return $self->{value} if ( defined wantarray );
}
sub cut_xss {
my $self = shift;
$self->{key} = shift if @_;
$self->{value} = shift if @_;
$self->_del_blanks_end_began;
$self->_clean_html;
return $self->{value} if (wantarray);
return $self;
}
sub exist_die {
my $self = shift;
$self->{key} = shift if @_;
$self->{value} = shift if @_;
$self->_add_all_fields();
if ( !$self->{value} ) {
$self->_add_bad_fields();
$self->{value} = undef;
$self->{key} = undef;
}
return $self->{value} if (wantarray);
return $self;
}
####
# Out fields all and bad
###
# получение массива или хэша SQL
sub out_all {
my $self = shift;
if ( defined $self->{all_arrey_out} && $self->all_fields_type eq 'arrey' ) {
return $self->{all_arrey_out};
}
if ( defined $self->{all_hash_out} && $self->all_fields_type eq 'hash' ) {
return $self->{all_hash_out};
}
}
# там где были ошибки
sub out_bad {
my $self = shift;
if ( defined @{ $self->{bad_arrey_out} }
&& $self->bad_fields_type eq 'arrey' )
{
return $self->{bad_arrey_out};
}
if ( defined $self->{bad_hash_out} && $self->bad_fields_type eq 'hash' ) {
return $self->{bad_hash_out};
}
}
# есть ли ошибки вывести 1
sub error_valid {
my $self = shift;
if ( $self->{bad_arrey_out} || $self->{bad_hash_out} ) {
return 1;
}
else {
return undef;
}
}
как работает:
Код: Выделить всё
my ( $self, $c, $edit_co ) = @_;
$c->stash->{template} = 'add_section.tt';
my $f = $c->model('ExtraDBI')->new; # инициализируються класс
$f->all_fields_type('hash'); # определяется что возвращать
$f->bad_fields_type('arrey'); #
# $c->request->params-> хэш форм
$f->cut_xss( 'name_co', $c->request->params->{name_content} )->exist_die; # Удаляется xss первый элемент ключ, второй значение
# дальше идет метод exist_die если нее введнео, то возращае ошибку
# в массив
$f->cut_xss( 'heading_name_co', $c->request->params->{name_head_content} )
->exist_die;
$f->cut_xss( 'keys_co', $c->request->params->{content_keys} )->exist_die;
$f->cut_xss( 'text_co', $c->request->params->{content_text} )->exist_die;
if ( $c->check_user_roles("moder_se") ) {
# проверяется включен ли элемент HTML check, вкл 1, выкл 0 и вставлется в хэш,
# дальше из него строиться SQL запрос, хэш отправляется в SQL::Abstarct
$f->int_check( 'hiden_g_co',
$c->request->params->{type_hiden_guest_content} );
$f->int_check( 'close_co', $c->request->params->{type_close_content} );
$f->int_check( 'active_co',
$c->request->params->{type_active_content} );
}
$f->int_check( 'hiden_co', $c->request->params->{type_hiden_content} );
$f->int_check( 'voting_co', $c->request->params->{type_voting_content} );
$f->int_check( 'forbi_comm_co', $c->request->params->{forbi_comm_co} );
my $sp;
if ( $c->request->params->{type_section_privat} eq 'on' ) {
$sp = 'AND privat_se = 1';
}
else {
$sp = 'AND privat_se = 0';
$f->no_sql->int_check( 'privat_se', 'on' );
}
if ( !$edit_co && !$c->request->params->{section_child2} ) {
$c->request->params->{section_child2} =
$c->request->params->{type_section_privat} eq '1' ? 1 : 35;
}
if (
$f->no_sql->valid_id( # это дейтсвие в SQL запрос не идет, если значение не цифра, то ошибка
'parent_se_id', $c->request->params->{section_child2}
)
)
{
my $dbh = $c->model('DBI')->dbh;
my $sth = $dbh->prepare(
"SELECT id_se,
id_un,
close_se,
active_se,
forbi_content_se,
privat_se
FROM section
WHERE id_se = ?
$sp
LIMIT 1"
);
$sth->execute( $c->request->params->{section_child2} );
my $section = $sth->fetchrow_hashref();
$sth->finish();
if ( $f->exist_die( 'id_se', $section->{id_se} ) ) { # если от сутствует - ошибка
if ( !$c->check_user_roles('moder_se') ) {
if ( $section->{active_se} == 0
&& $section->{id_un} != $c->user->{user}->{id} )
{
$f->no_sql->zero_die( 'active_se', 0 );
}
$f->no_sql->zero_die( 'forbi_content_se',
$section->{forbi_content_se} );
}
}
}
if ($edit_co) {
$f->no_sql->exist_die( 'no_edit_id_co',
$c->request->params->{edit_id_co} );
if ( !$c->check_user_roles('moder_se') ) {
my $dbh = $c->model('DBI')->dbh;
my $sth = $dbh->prepare(
"SELECT id_co,
close_co,
id_un
FROM content
WHERE id_co = ?
LIMIT 1"
);
$sth->execute( $c->request->params->{edit_id_co} );
my $section = $sth->fetchrow_hashref();
$sth->finish();
$f->no_sql->zero_die( 'close_co', $section->{close_se} );
if ( $section->{id_un} == $c->user->{user}->{id} ) {
$f->no_sql->zero_die( 'id_un_no_co', 0 );
}
}
}
# если найдена ошибка, то пропускате обработку СУБД
if ( !$f->error_valid ) {
# если ошибок нету
my $hash = $f->out_all; # получаем хэш SQL
my $type_sql;
my $where; # ддополнительный хэш условие SQL
if ($edit_co) { # если текущее дейтсвие редактирвоание
$type_sql = 'update'; # sql действие для модуля SQL::Abstarct
$where->{id_co} = $c->request->params->{edit_id_co};
$where->{id_un} = $c->user->{user}->{id}
if ( !$c->check_user_roles('moder_co') );
$hash->{modified} = time;
}
if ( !$edit_co ) { # аналогично, не редактирование
if ( !$c->check_user_roles("moder_se") ) {
$hash->{hiden_g_co} = 0;
$hash->{close_co} = 0;
$hash->{active_co} = 0;
}
$type_sql = 'insert';
$hash->{created} = time;
$hash->{id_un} = $c->user->{user}->{id};
}
use SQL::Abstract;
my $sql = SQL::Abstract->new;
# генерим запрос, таблицы content
my ( $stmt, @bind ) = $sql->$type_sql( 'content', $hash, $where );
my $dbh = $c->model('DBI')->dbh;
my $sth = $dbh->prepare($stmt);
$sth->execute(@bind);
$sth->finish();
# выполнили
my $lastid = $dbh->{mysql_insertid} unless ($edit_co); # последний элемент для редиректа
my $url;
# редиректим в зависимости от условия
my $redirect_id =
$edit_co ? $c->request->params->{edit_id_co} : $lastid;
if ( $c->request->params->{type_redirect} eq 'on' ) {
$url = '/profile/edit_pesonal_content/' . $redirect_id;
}
else {
$url = '/view_content/' . $redirect_id;
}
$c->response->redirect( $c->uri_for($url) );
$c->detach();
}
else { если ошибка была, которая не должна быть и наче SQL запро не сработает
my $out_all = $f->out_all; # получить все элементы чтобы заполнить обратно формы ШТМЛ
my $out_bad = $f->out_bad; # там где была ошибка
$c->stash->{bad_form} = 1; # ошибка, $c->stash-> хэш котоырй эиет в шаблон ШТМЛ
while ( my ( $key, $value ) = each( %{$out_all} ) ) { # разымунует ссылки на хэш и в шаблон
$c->stash->{ $key . '_current' } = $value;
}
foreach ( @{$out_bad} ) { # все плохие, то же самое мааси через ссылку
$_ .= $_ . '_error' if ( $_ eq 'id_se' );
$c->stash->{$_} = 1;
}
# возвращется обратно в зависимости редактирование или добавление
if ( !$edit_co ) {
$c->forward( 'add_content',
[ $c->request->params->{section_child2} ] );
}
else {
$c->forward( 'edit_pesonal_content',
[ $c->request->params->{section_child2} ] );
}
$c->detach();
}