|
Lines 254-281
sub SimpleSearch {
Link Here
|
| 254 |
return ( $error, undef, undef ); |
254 |
return ( $error, undef, undef ); |
| 255 |
} |
255 |
} |
| 256 |
} |
256 |
} |
| 257 |
while ( ( my $i = ZOOM::event( \@zconns ) ) != 0 ) { |
|
|
| 258 |
my $event = $zconns[ $i - 1 ]->last_event(); |
| 259 |
if ( $event == ZOOM::Event::ZEND ) { |
| 260 |
|
257 |
|
| 261 |
my $first_record = defined( $offset ) ? $offset+1 : 1; |
258 |
_ZOOM_event_loop( |
|
|
259 |
\@zconns, |
| 260 |
\@tmpresults, |
| 261 |
sub { |
| 262 |
my ($i, $size) = @_; |
| 263 |
my $first_record = defined($offset) ? $offset + 1 : 1; |
| 262 |
my $hits = $tmpresults[ $i - 1 ]->size(); |
264 |
my $hits = $tmpresults[ $i - 1 ]->size(); |
| 263 |
$total_hits += $hits; |
265 |
$total_hits += $hits; |
| 264 |
my $last_record = $hits; |
266 |
my $last_record = $hits; |
| 265 |
if ( defined $max_results && $offset + $max_results < $hits ) { |
267 |
if ( defined $max_results && $offset + $max_results < $hits ) { |
| 266 |
$last_record = $offset + $max_results; |
268 |
$last_record = $offset + $max_results; |
| 267 |
} |
269 |
} |
| 268 |
|
270 |
|
| 269 |
for my $j ( $first_record..$last_record ) { |
271 |
for my $j ( $first_record .. $last_record ) { |
| 270 |
my $record = $tmpresults[ $i - 1 ]->record( $j-1 )->raw(); # 0 indexed |
272 |
my $record = |
|
|
273 |
$tmpresults[ $i - 1 ]->record( $j - 1 )->raw() |
| 274 |
; # 0 indexed |
| 271 |
push @{$results}, $record; |
275 |
push @{$results}, $record; |
| 272 |
} |
276 |
} |
| 273 |
} |
277 |
} |
| 274 |
} |
278 |
); |
| 275 |
|
279 |
|
| 276 |
foreach my $result (@tmpresults) { |
|
|
| 277 |
$result->destroy(); |
| 278 |
} |
| 279 |
foreach my $zoom_query (@zoom_queries) { |
280 |
foreach my $zoom_query (@zoom_queries) { |
| 280 |
$zoom_query->destroy(); |
281 |
$zoom_query->destroy(); |
| 281 |
} |
282 |
} |
|
Lines 410-421
sub getRecords {
Link Here
|
| 410 |
} # finished looping through servers |
411 |
} # finished looping through servers |
| 411 |
|
412 |
|
| 412 |
# The big moment: asynchronously retrieve results from all servers |
413 |
# The big moment: asynchronously retrieve results from all servers |
| 413 |
while ( ( my $i = ZOOM::event( \@zconns ) ) != 0 ) { |
414 |
_ZOOM_event_loop( |
| 414 |
my $ev = $zconns[ $i - 1 ]->last_event(); |
415 |
\@zconns, |
| 415 |
if ( $ev == ZOOM::Event::ZEND ) { |
416 |
\@results, |
| 416 |
next unless $results[ $i - 1 ]; |
417 |
sub { |
| 417 |
my $size = $results[ $i - 1 ]->size(); |
418 |
my ( $i, $size ) = @_; |
| 418 |
if ( $size > 0 ) { |
|
|
| 419 |
my $results_hash; |
419 |
my $results_hash; |
| 420 |
|
420 |
|
| 421 |
# loop through the results |
421 |
# loop through the results |
|
Lines 444-459
sub getRecords {
Link Here
|
| 444 |
my $tmpauthor; |
444 |
my $tmpauthor; |
| 445 |
|
445 |
|
| 446 |
# the minimal record in author/title (depending on MARC flavour) |
446 |
# the minimal record in author/title (depending on MARC flavour) |
| 447 |
if (C4::Context->preference("marcflavour") eq "UNIMARC") { |
447 |
if ( C4::Context->preference("marcflavour") eq |
| 448 |
$tmptitle = MARC::Field->new('200',' ',' ', a => $term, f => $occ); |
448 |
"UNIMARC" ) |
|
|
449 |
{ |
| 450 |
$tmptitle = MARC::Field->new( |
| 451 |
'200', ' ', ' ', |
| 452 |
a => $term, |
| 453 |
f => $occ |
| 454 |
); |
| 449 |
$tmprecord->append_fields($tmptitle); |
455 |
$tmprecord->append_fields($tmptitle); |
| 450 |
} else { |
456 |
} |
| 451 |
$tmptitle = MARC::Field->new('245',' ',' ', a => $term,); |
457 |
else { |
| 452 |
$tmpauthor = MARC::Field->new('100',' ',' ', a => $occ,); |
458 |
$tmptitle = |
|
|
459 |
MARC::Field->new( '245', ' ', ' ', a => $term, ); |
| 460 |
$tmpauthor = |
| 461 |
MARC::Field->new( '100', ' ', ' ', a => $occ, ); |
| 453 |
$tmprecord->append_fields($tmptitle); |
462 |
$tmprecord->append_fields($tmptitle); |
| 454 |
$tmprecord->append_fields($tmpauthor); |
463 |
$tmprecord->append_fields($tmpauthor); |
| 455 |
} |
464 |
} |
| 456 |
$results_hash->{'RECORDS'}[$j] = $tmprecord->as_usmarc(); |
465 |
$results_hash->{'RECORDS'}[$j] = |
|
|
466 |
$tmprecord->as_usmarc(); |
| 457 |
} |
467 |
} |
| 458 |
|
468 |
|
| 459 |
# not an index scan |
469 |
# not an index scan |
|
Lines 467-609
sub getRecords {
Link Here
|
| 467 |
} |
477 |
} |
| 468 |
$results_hashref->{ $servers[ $i - 1 ] } = $results_hash; |
478 |
$results_hashref->{ $servers[ $i - 1 ] } = $results_hash; |
| 469 |
|
479 |
|
| 470 |
# Fill the facets while we're looping, but only for the biblioserver and not for a scan |
480 |
# Fill the facets while we're looping, but only for the biblioserver and not for a scan |
| 471 |
if ( !$scan && $servers[ $i - 1 ] =~ /biblioserver/ ) { |
481 |
if ( !$scan && $servers[ $i - 1 ] =~ /biblioserver/ ) { |
| 472 |
|
482 |
|
| 473 |
my $jmax = $size>$facets_maxrecs? $facets_maxrecs: $size; |
483 |
my $jmax = |
| 474 |
for my $facet ( @$facets ) { |
484 |
$size > $facets_maxrecs ? $facets_maxrecs : $size; |
| 475 |
for ( my $j = 0 ; $j < $jmax ; $j++ ) { |
485 |
for my $facet (@$facets) { |
| 476 |
my $render_record = $results[ $i - 1 ]->record($j)->render(); |
486 |
for ( my $j = 0 ; $j < $jmax ; $j++ ) { |
|
|
487 |
my $render_record = |
| 488 |
$results[ $i - 1 ]->record($j)->render(); |
| 477 |
my @used_datas = (); |
489 |
my @used_datas = (); |
| 478 |
foreach my $tag ( @{$facet->{tags}} ) { |
490 |
foreach my $tag ( @{ $facet->{tags} } ) { |
|
|
491 |
|
| 479 |
# avoid first line |
492 |
# avoid first line |
| 480 |
my $tag_num = substr($tag, 0, 3); |
493 |
my $tag_num = substr( $tag, 0, 3 ); |
| 481 |
my $letters = substr($tag, 3); |
494 |
my $letters = substr( $tag, 3 ); |
| 482 |
my $field_pattern = '\n' . $tag_num . ' ([^z][^\n]+)'; |
495 |
my $field_pattern = |
| 483 |
$field_pattern = '\n' . $tag_num . ' ([^\n]+)' if (int($tag_num) < 10); |
496 |
'\n' . $tag_num . ' ([^z][^\n]+)'; |
| 484 |
my @field_tokens = ( $render_record =~ /$field_pattern/g ) ; |
497 |
$field_pattern = '\n' . $tag_num . ' ([^\n]+)' |
|
|
498 |
if ( int($tag_num) < 10 ); |
| 499 |
my @field_tokens = |
| 500 |
( $render_record =~ /$field_pattern/g ); |
| 485 |
foreach my $field_token (@field_tokens) { |
501 |
foreach my $field_token (@field_tokens) { |
| 486 |
my @subf = ( $field_token =~ /\$([a-zA-Z0-9]) ([^\$]+)/g ); |
502 |
my @subf = ( $field_token =~ |
|
|
503 |
/\$([a-zA-Z0-9]) ([^\$]+)/g ); |
| 487 |
my @values; |
504 |
my @values; |
| 488 |
for (my $i = 0; $i < @subf; $i += 2) { |
505 |
for ( my $i = 0 ; $i < @subf ; $i += 2 ) { |
| 489 |
if ( $letters =~ $subf[$i] ) { |
506 |
if ( $letters =~ $subf[$i] ) { |
| 490 |
my $value = $subf[$i+1]; |
507 |
my $value = $subf[ $i + 1 ]; |
| 491 |
$value =~ s/^ *//; |
508 |
$value =~ s/^ *//; |
| 492 |
$value =~ s/ *$//; |
509 |
$value =~ s/ *$//; |
| 493 |
push @values, $value; |
510 |
push @values, $value; |
| 494 |
} |
511 |
} |
| 495 |
} |
512 |
} |
| 496 |
my $data = join($facet->{sep}, @values); |
513 |
my $data = join( $facet->{sep}, @values ); |
| 497 |
unless ( $data ~~ @used_datas ) { |
514 |
unless ( $data ~~ @used_datas ) { |
| 498 |
$facets_counter->{ $facet->{idx} }->{$data}++; |
515 |
$facets_counter->{ $facet->{idx} } |
|
|
516 |
->{$data}++; |
| 499 |
push @used_datas, $data; |
517 |
push @used_datas, $data; |
| 500 |
} |
518 |
} |
| 501 |
} # fields |
519 |
} # fields |
| 502 |
} # field codes |
520 |
} # field codes |
| 503 |
} # records |
521 |
} # records |
| 504 |
$facets_info->{ $facet->{idx} }->{label_value} = $facet->{label}; |
522 |
$facets_info->{ $facet->{idx} }->{label_value} = |
| 505 |
$facets_info->{ $facet->{idx} }->{expanded} = $facet->{expanded}; |
523 |
$facet->{label}; |
| 506 |
} # facets |
524 |
$facets_info->{ $facet->{idx} }->{expanded} = |
|
|
525 |
$facet->{expanded}; |
| 526 |
} # facets |
| 507 |
} |
527 |
} |
| 508 |
} |
|
|
| 509 |
|
528 |
|
| 510 |
# warn "connection ", $i-1, ": $size hits"; |
529 |
# warn "connection ", $i-1, ": $size hits"; |
| 511 |
# warn $results[$i-1]->record(0)->render() if $size > 0; |
530 |
# warn $results[$i-1]->record(0)->render() if $size > 0; |
| 512 |
|
531 |
|
| 513 |
# BUILD FACETS |
532 |
# BUILD FACETS |
| 514 |
if ( $servers[ $i - 1 ] =~ /biblioserver/ ) { |
533 |
if ( $servers[ $i - 1 ] =~ /biblioserver/ ) { |
| 515 |
for my $link_value ( |
534 |
for my $link_value ( |
| 516 |
sort { $facets_counter->{$b} <=> $facets_counter->{$a} } |
535 |
sort { $facets_counter->{$b} <=> $facets_counter->{$a} } |
| 517 |
keys %$facets_counter ) |
536 |
keys %$facets_counter |
| 518 |
{ |
|
|
| 519 |
my $expandable; |
| 520 |
my $number_of_facets; |
| 521 |
my @this_facets_array; |
| 522 |
for my $one_facet ( |
| 523 |
sort { |
| 524 |
$facets_counter->{$link_value}->{$b} |
| 525 |
<=> $facets_counter->{$link_value}->{$a} |
| 526 |
} keys %{ $facets_counter->{$link_value} } |
| 527 |
) |
537 |
) |
| 528 |
{ |
538 |
{ |
| 529 |
$number_of_facets++; |
539 |
my $expandable; |
| 530 |
if ( ( $number_of_facets < 6 ) |
540 |
my $number_of_facets; |
| 531 |
|| ( $expanded_facet eq $link_value ) |
541 |
my @this_facets_array; |
| 532 |
|| ( $facets_info->{$link_value}->{'expanded'} ) ) |
542 |
for my $one_facet ( |
|
|
543 |
sort { |
| 544 |
$facets_counter->{$link_value} |
| 545 |
->{$b} <=> $facets_counter->{$link_value} |
| 546 |
->{$a} |
| 547 |
} keys %{ $facets_counter->{$link_value} } |
| 548 |
) |
| 533 |
{ |
549 |
{ |
|
|
550 |
$number_of_facets++; |
| 551 |
if ( ( $number_of_facets < 6 ) |
| 552 |
|| ( $expanded_facet eq $link_value ) |
| 553 |
|| ( $facets_info->{$link_value}->{'expanded'} ) |
| 554 |
) |
| 555 |
{ |
| 556 |
|
| 557 |
# Sanitize the link value : parenthesis, question and exclamation mark will cause errors with CCL |
| 558 |
my $facet_link_value = $one_facet; |
| 559 |
$facet_link_value =~ s/[()!?¡¿؟]/ /g; |
| 560 |
|
| 561 |
# fix the length that will display in the label, |
| 562 |
my $facet_label_value = $one_facet; |
| 563 |
my $facet_max_length = C4::Context->preference( |
| 564 |
'FacetLabelTruncationLength') |
| 565 |
|| 20; |
| 566 |
$facet_label_value = |
| 567 |
substr( $one_facet, 0, $facet_max_length ) |
| 568 |
. "..." |
| 569 |
if length($facet_label_value) > |
| 570 |
$facet_max_length; |
| 534 |
|
571 |
|
| 535 |
# Sanitize the link value : parenthesis, question and exclamation mark will cause errors with CCL |
572 |
# if it's a branch, label by the name, not the code, |
| 536 |
my $facet_link_value = $one_facet; |
573 |
if ( $link_value =~ /branch/ ) { |
| 537 |
$facet_link_value =~ s/[()!?¡¿؟]/ /g; |
574 |
if ( defined $branches |
|
|
575 |
&& ref($branches) eq "HASH" |
| 576 |
&& defined $branches->{$one_facet} |
| 577 |
&& ref( $branches->{$one_facet} ) eq |
| 578 |
"HASH" ) |
| 579 |
{ |
| 580 |
$facet_label_value = |
| 581 |
$branches->{$one_facet} |
| 582 |
->{'branchname'}; |
| 583 |
} |
| 584 |
else { |
| 585 |
$facet_label_value = "*"; |
| 586 |
} |
| 587 |
} |
| 538 |
|
588 |
|
| 539 |
# fix the length that will display in the label, |
589 |
# if it's a itemtype, label by the name, not the code, |
| 540 |
my $facet_label_value = $one_facet; |
590 |
if ( $link_value =~ /itype/ ) { |
| 541 |
my $facet_max_length = |
591 |
if ( defined $itemtypes |
| 542 |
C4::Context->preference('FacetLabelTruncationLength') || 20; |
592 |
&& ref($itemtypes) eq "HASH" |
| 543 |
$facet_label_value = |
593 |
&& defined $itemtypes->{$one_facet} |
| 544 |
substr( $one_facet, 0, $facet_max_length ) . "..." |
594 |
&& ref( $itemtypes->{$one_facet} ) eq |
| 545 |
if length($facet_label_value) > $facet_max_length; |
595 |
"HASH" ) |
|
|
596 |
{ |
| 597 |
$facet_label_value = |
| 598 |
$itemtypes->{$one_facet} |
| 599 |
->{'description'}; |
| 600 |
} |
| 601 |
} |
| 546 |
|
602 |
|
| 547 |
# if it's a branch, label by the name, not the code, |
603 |
# also, if it's a location code, use the name instead of the code |
| 548 |
if ( $link_value =~ /branch/ ) { |
604 |
if ( $link_value =~ /location/ ) { |
| 549 |
if (defined $branches |
|
|
| 550 |
&& ref($branches) eq "HASH" |
| 551 |
&& defined $branches->{$one_facet} |
| 552 |
&& ref ($branches->{$one_facet}) eq "HASH") |
| 553 |
{ |
| 554 |
$facet_label_value = |
| 555 |
$branches->{$one_facet}->{'branchname'}; |
| 556 |
} |
| 557 |
else { |
| 558 |
$facet_label_value = "*"; |
| 559 |
} |
| 560 |
} |
| 561 |
# if it's a itemtype, label by the name, not the code, |
| 562 |
if ( $link_value =~ /itype/ ) { |
| 563 |
if (defined $itemtypes |
| 564 |
&& ref($itemtypes) eq "HASH" |
| 565 |
&& defined $itemtypes->{$one_facet} |
| 566 |
&& ref ($itemtypes->{$one_facet}) eq "HASH") |
| 567 |
{ |
| 568 |
$facet_label_value = |
605 |
$facet_label_value = |
| 569 |
$itemtypes->{$one_facet}->{'description'}; |
606 |
GetKohaAuthorisedValueLib( 'LOC', |
|
|
607 |
$one_facet, $opac ); |
| 570 |
} |
608 |
} |
| 571 |
} |
|
|
| 572 |
|
609 |
|
| 573 |
# also, if it's a location code, use the name instead of the code |
610 |
# but we're down with the whole label being in the link's title. |
| 574 |
if ( $link_value =~ /location/ ) { |
611 |
push @this_facets_array, |
| 575 |
$facet_label_value = GetKohaAuthorisedValueLib('LOC', $one_facet, $opac); |
612 |
{ |
|
|
613 |
facet_count => |
| 614 |
$facets_counter->{$link_value} |
| 615 |
->{$one_facet}, |
| 616 |
facet_label_value => $facet_label_value, |
| 617 |
facet_title_value => $one_facet, |
| 618 |
facet_link_value => $facet_link_value, |
| 619 |
type_link_value => $link_value, |
| 620 |
} |
| 621 |
if ($facet_label_value); |
| 576 |
} |
622 |
} |
| 577 |
|
|
|
| 578 |
# but we're down with the whole label being in the link's title. |
| 579 |
push @this_facets_array, { |
| 580 |
facet_count => $facets_counter->{$link_value}->{$one_facet}, |
| 581 |
facet_label_value => $facet_label_value, |
| 582 |
facet_title_value => $one_facet, |
| 583 |
facet_link_value => $facet_link_value, |
| 584 |
type_link_value => $link_value, |
| 585 |
} if ( $facet_label_value ); |
| 586 |
} |
623 |
} |
| 587 |
} |
|
|
| 588 |
|
624 |
|
| 589 |
# handle expanded option |
625 |
# handle expanded option |
| 590 |
unless ( $facets_info->{$link_value}->{'expanded'} ) { |
626 |
unless ( $facets_info->{$link_value}->{'expanded'} ) { |
| 591 |
$expandable = 1 |
627 |
$expandable = 1 |
| 592 |
if ( ( $number_of_facets > 6 ) |
628 |
if ( ( $number_of_facets > 6 ) |
| 593 |
&& ( $expanded_facet ne $link_value ) ); |
629 |
&& ( $expanded_facet ne $link_value ) ); |
|
|
630 |
} |
| 631 |
push @facets_loop, |
| 632 |
{ |
| 633 |
type_link_value => $link_value, |
| 634 |
type_id => $link_value . "_id", |
| 635 |
"type_label_" |
| 636 |
. $facets_info->{$link_value}->{'label_value'} => |
| 637 |
1, |
| 638 |
facets => \@this_facets_array, |
| 639 |
expandable => $expandable, |
| 640 |
expand => $link_value, |
| 641 |
} |
| 642 |
unless ( |
| 643 |
( |
| 644 |
$facets_info->{$link_value}->{'label_value'} =~ |
| 645 |
/Libraries/ |
| 646 |
) |
| 647 |
and ( C4::Context->preference('singleBranchMode') ) |
| 648 |
); |
| 594 |
} |
649 |
} |
| 595 |
push @facets_loop, { |
|
|
| 596 |
type_link_value => $link_value, |
| 597 |
type_id => $link_value . "_id", |
| 598 |
"type_label_" . $facets_info->{$link_value}->{'label_value'} => 1, |
| 599 |
facets => \@this_facets_array, |
| 600 |
expandable => $expandable, |
| 601 |
expand => $link_value, |
| 602 |
} unless ( ($facets_info->{$link_value}->{'label_value'} =~ /Libraries/) and (C4::Context->preference('singleBranchMode')) ); |
| 603 |
} |
650 |
} |
| 604 |
} |
651 |
} |
| 605 |
} |
652 |
); |
| 606 |
} |
|
|
| 607 |
return ( undef, $results_hashref, \@facets_loop ); |
653 |
return ( undef, $results_hashref, \@facets_loop ); |
| 608 |
} |
654 |
} |
| 609 |
|
655 |
|
|
Lines 2816-2839
sub GetDistinctValues {
Link Here
|
| 2816 |
} |
2862 |
} |
| 2817 |
# The big moment: asynchronously retrieve results from all servers |
2863 |
# The big moment: asynchronously retrieve results from all servers |
| 2818 |
my @elements; |
2864 |
my @elements; |
| 2819 |
while ( ( my $i = ZOOM::event( \@zconns ) ) != 0 ) { |
2865 |
_ZOOM_event_loop( |
| 2820 |
my $ev = $zconns[ $i - 1 ]->last_event(); |
2866 |
\@zconns, |
| 2821 |
if ( $ev == ZOOM::Event::ZEND ) { |
2867 |
\@results, |
| 2822 |
next unless $results[ $i - 1 ]; |
2868 |
sub { |
| 2823 |
my $size = $results[ $i - 1 ]->size(); |
2869 |
my ( $i, $size ) = @_; |
| 2824 |
if ( $size > 0 ) { |
2870 |
for ( my $j = 0 ; $j < $size ; $j++ ) { |
| 2825 |
for (my $j=0;$j<$size;$j++){ |
2871 |
my %hashscan; |
| 2826 |
my %hashscan; |
2872 |
@hashscan{qw(value cnt)} = |
| 2827 |
@hashscan{qw(value cnt)}=$results[ $i - 1 ]->display_term($j); |
2873 |
$results[ $i - 1 ]->display_term($j); |
| 2828 |
push @elements, \%hashscan; |
2874 |
push @elements, \%hashscan; |
| 2829 |
} |
2875 |
} |
| 2830 |
} |
2876 |
} |
| 2831 |
} |
2877 |
); |
| 2832 |
} |
|
|
| 2833 |
return \@elements; |
2878 |
return \@elements; |
| 2834 |
} |
2879 |
} |
| 2835 |
} |
2880 |
} |
| 2836 |
|
2881 |
|
|
|
2882 |
=head2 _ZOOM_event_loop |
| 2883 |
|
| 2884 |
_ZOOM_event_loop(\@zconns, \@results, sub { |
| 2885 |
my ( $i, $size ) = @_; |
| 2886 |
.... |
| 2887 |
} ); |
| 2888 |
|
| 2889 |
Processes a ZOOM event loop and passes control to a closure for |
| 2890 |
processing the results, and destroying the resultsets. |
| 2891 |
|
| 2892 |
=cut |
| 2893 |
|
| 2894 |
sub _ZOOM_event_loop { |
| 2895 |
my ($zconns, $results, $callback) = @_; |
| 2896 |
while ( ( my $i = ZOOM::event( $zconns ) ) != 0 ) { |
| 2897 |
my $ev = $zconns->[ $i - 1 ]->last_event(); |
| 2898 |
if ( $ev == ZOOM::Event::ZEND ) { |
| 2899 |
next unless $results->[ $i - 1 ]; |
| 2900 |
my $size = $results->[ $i - 1 ]->size(); |
| 2901 |
if ( $size > 0 ) { |
| 2902 |
$callback->($i, $size); |
| 2903 |
} |
| 2904 |
} |
| 2905 |
} |
| 2906 |
|
| 2907 |
foreach my $result (@$results) { |
| 2908 |
$result->destroy(); |
| 2909 |
} |
| 2910 |
} |
| 2911 |
|
| 2837 |
|
2912 |
|
| 2838 |
END { } # module clean-up code here (global destructor) |
2913 |
END { } # module clean-up code here (global destructor) |
| 2839 |
|
2914 |
|
| 2840 |
- |
|
|