Revision 608
- Date:
- 2016/11/01 18:52:39
- Files:
Legend:
- Added
- Removed
- Modified
-
utf8/core/lib/Contenido/Section.pm
64 64 class_table()->new(); 65 65 } 66 66 67 sub pre_store { 68 my $self = shift; 69 67 70 if ( $self->id && !$self->{__light} ) { 71 ### Autofill or autoflush documents order if applicable 72 if ( $self->_sorted && !$self->_sorted_order ) { 73 my %opts; 74 if ( $self->default_document_class ) { 75 $opts{class} = $self->default_document_class; 76 } elsif ( $self->default_table_class ) { 77 $opts{table} = $self->default_table_class; 78 } else { 79 $opts{table} = 'Contenido::SQL::DocumentTable'; 80 } 81 if ( $self->order_by ) { 82 $opts{order_by} = $self->order_by; 83 } 84 if ( $self->filters ) { 85 no strict 'vars'; 86 my $filters = eval($self->filters); 87 if ($@) { 88 warn "Bad filter: " . $self->filters . " in section " . $self->id; 89 } elsif (ref $filters eq 'HASH') { 90 while ( my ($key, $val) = each %$filters ) { 91 $opts{$key} = $val; 92 } 93 } 94 } 95 my $ids = $keeper->get_documents( s => $self->id, %opts, ids => 1, return_mode => 'array_ref' ); 96 $self->_sorted_order( join(',', @$ids) ); 97 } elsif ( !$self->_sorted && $self->_sorted_order ) { 98 $self->_sorted_order( undef ); 99 } 100 } 101 102 1; 103 } 104 105 68 #доработка метода store 106 69 sub store { 107 my $self=shift; 70 my $self = shift; 71 my (%opts) = @_; 108 72 109 73 #для новосозданных секций ставим новый sorder 110 unless ($self->{id}) { 111 my ($sorder) = $self->keeper->SQL->selectrow_array("select max(sorder) from ".$self->class_table->db_table(), {}); 112 $self->{sorder} = $sorder + 1; 74 if ( $self->{id} ) { 75 my $without_sort = delete $opts{without_sort}; 76 unless ( $without_sort || $self->{__light} ) { 77 ### Autofill or autoflush documents order if applicable 78 if ( $self->_sorted ) { 79 my $ids = $self->_get_document_order; 80 $self->_sorted_order( join(',', @$ids) ); 81 } elsif ( !$self->_sorted && $self->_sorted_order ) { 82 $self->_sorted_order( undef ); 83 } 84 } 85 } else { 86 my ($sorder) = $self->keeper->SQL->selectrow_array("select max(sorder) from ".$self->class_table->db_table(), {}); 87 $self->{sorder} = $sorder + 1; 113 88 } 114 89 115 90 return $self->SUPER::store(); … … 223 198 } 224 199 225 200 201 sub _get_document_order { 202 my ($self) = shift; 226 203 204 my @order = $self->_sorted_order ? split( /,/, $self->_sorted_order ) : (); 205 206 my %opts; 207 if ( $self->default_document_class ) { 208 $opts{class} = $self->default_document_class; 209 } elsif ( $self->default_table_class ) { 210 $opts{table} = $self->default_table_class; 211 } else { 212 $opts{table} = 'Contenido::SQL::DocumentTable'; 213 } 214 if ( $self->order_by ) { 215 $opts{order_by} = $self->order_by; 216 } 217 if ( $self->filters ) { 218 no strict 'vars'; 219 my $filters = eval($self->filters); 220 if ($@) { 221 warn "Bad filter: " . $self->filters . " in section " . $self->id; 222 } elsif (ref $filters eq 'HASH') { 223 while ( my ($key, $val) = each %$filters ) { 224 $opts{$key} = $val; 225 } 226 } 227 } 228 my $ids = $keeper->get_documents( s => $self->id, %opts, ids => 1, return_mode => 'array_ref' ); 229 my %ids = map { $_ => 1 } @$ids; 230 my @new_order; 231 foreach my $iid ( @order ) { 232 if ( exists $ids{$iid} ) { 233 push @new_order, $iid; 234 delete $ids{$iid}; 235 } 236 } 237 foreach my $iid ( @$ids ) { 238 if ( exists $ids{$iid} ) { 239 push @new_order, $iid; 240 delete $ids{$iid}; 241 } 242 } 243 return \@new_order; 244 } 245 246 227 247 # ---------------------------------------------------------------------------- 228 248 # Метод для перемещение секции вверх/вниз по рубрикатору (изменение 229 249 # sorder)... … … 289 309 # $doc->dmove($doc_id, $direction); Направление задается строкой 'up'/'down' 290 310 # ---------------------------------------------------------------------------- 291 311 sub dmove { 292 my ($self, $doc_id, $direction) = @_; 312 my ($self, $doc_id, $direction, $anchor) = @_; 293 313 do { $log->error("Метод ->dmove() можно вызывать только у объектов, но не классов"); die } unless ref($self); 294 314 295 315 return undef if ($self->keeper->state->readonly()); … … 300 320 unless (exists($self->{id}) && ($self->{id} > 0)); 301 321 302 322 $direction = lc($direction); 303 if ( ($direction ne 'up') && ($direction ne 'down') ) { $log->warning("Направление перемещения документа задано неверно"); return undef }; 323 unless ( $direction eq 'up' || $direction eq 'down' || $direction eq 'first' || $direction eq 'last' || $direction eq 'before' || $direction eq 'after' ) { 324 $log->warning("Направление перемещения документа задано неверно"); return undef 325 }; 326 my $anchor_flag = 0; 327 if ( ($direction eq 'before' || $direction eq 'after') && !$anchor ) { 328 $log->warning("Неверный вызов функции dmove для направления '$direction'. Необходимо указать дополнительно id в списке документов"); return undef; 329 } elsif ( $direction eq 'before' || $direction eq 'after' ) { 330 $anchor_flag = 1; 331 } 304 332 305 my $sorder_; 306 333 if ($self->_sorted()) { 307 my @ids = $keeper->get_documents( ids =>1, s => $self->id(), 308 ($self->default_document_class ? (class => $self->default_document_class) : $self->default_table_class ? (table => $self->default_table_class) : ()), 309 order => ['date', undef], light => 1 310 ); 311 my %ids = map { $_ => 1 } @ids; 312 unless ($self->{_sorted_order}) { 313 $self->{_sorted_order} = join ',', @ids; 314 } 334 my $order = $self->_get_document_order; 335 my @new_order; 336 if ( $direction eq 'first' ) { 337 push @new_order, $doc_id; 338 } 339 for ( my $i = 0; $i < scalar @$order; $i++ ) { 340 if ( ($direction eq 'first' || $direction eq 'last' || $direction eq 'after' || $direction eq 'before') && $order->[$i] == $doc_id ) { 341 next; 342 } elsif ( $direction eq 'up' && $order->[$i] == $doc_id ) { 343 if ( $i ) { 344 my $id = pop @new_order; 345 push @new_order, ($doc_id, $id); 346 } else { 347 push @new_order, $doc_id; 348 } 349 } elsif ( $direction eq 'down' && $order->[$i] == $doc_id ) { 350 if ( $i < scalar(@$order) - 1 ) { 351 push @new_order, ($order->[++$i], $doc_id); 352 } else { 353 push @new_order, $doc_id; 354 } 355 } elsif ( $direction eq 'before' && $order->[$i] == $anchor ) { 356 push @new_order, ($doc_id, $order->[$i]); 357 $anchor_flag = 0; 358 } elsif ( $direction eq 'after' && $order->[$i] == $anchor ) { 359 push @new_order, ($order->[$i], $doc_id); 360 $anchor_flag = 0; 361 } else { 362 push @new_order, $order->[$i]; 363 } 364 } 365 if ( $anchor_flag ) { 366 $log->warning("Неверный вызов функции dmove для направления '$direction'. Не найден якорь [$anchor]"); return undef; 367 } 368 if ( $direction eq 'last' ) { 369 push @new_order, $doc_id; 370 } 315 371 316 my @order = split(/,/, $self->{_sorted_order}); 317 @order = grep { 318 my $res; 319 if (exists $ids{$_}) { 320 $res = 1; 321 delete $ids{$_}; 322 } 323 $res 324 } @order; 325 326 push @order, keys %ids; 327 328 foreach my $i (0 .. $#order) { 329 if ($order[$i] == $doc_id) { 330 my $t; 331 if ($direction eq 'up') { 332 last if $i == 0; 333 $t = $order[$i-1]; 334 $order[$i-1] = $order[$i]; 335 $order[$i] = $t; 336 $sorder_ = $i - 1; 337 last; 338 } elsif ($direction eq 'down') { 339 last if $i == $#order; 340 $t = $order[$i+1]; 341 $order[$i+1] = $order[$i]; 342 $order[$i] = $t; 343 $sorder_ = $i + 1; 344 last; 345 } 346 } 347 } 348 349 $self->{_sorted_order} = join ',', @order; 350 $self->store(); 372 $self->{_sorted_order} = join ',', @new_order; 373 $self->store( without_sort => 1 ); 351 374 } else { 352 $log->warning("dmove called for section without enabled sorted feature... $self->{id}/$self->{class}"); 375 $log->warning("dmove called for section without enabled sorted feature... ".$self->id."/".$self->class); 353 376 } 354 377 355 $self->{sorder} = $sorder_; 356 378 return 1; 357 379 } 358 380