X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FSearch.pm;h=8a62a40882a8f38baaa11119d6f2130082e7feb5;hb=3dd5fccccc4c50778cc80052d5f750cc6a423874;hp=8f3410f46481a5c0ed7cd9120b2ed9b36336d2cd;hpb=3037ff9e81149615f94d3c4ff0e5b4c5240f3ce9;p=koha.git
diff --git a/C4/Search.pm b/C4/Search.pm
index 8f3410f464..8a62a40882 100644
--- a/C4/Search.pm
+++ b/C4/Search.pm
@@ -27,6 +27,8 @@ use XML::Simple;
use C4::Dates qw(format_date);
use C4::XSLT;
use C4::Branch;
+use C4::Debug;
+use YAML;
use URI::Escape;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
@@ -58,6 +60,7 @@ This module provides searching functions for Koha's bibliographic databases
&FindDuplicate
&SimpleSearch
&searchResults
+ &SearchAcquisitions
&getRecords
&buildQuery
&NZgetRecords
@@ -633,10 +636,12 @@ sub _remove_stopwords {
# we use IsAlpha unicode definition, to deal correctly with diacritics.
# otherwise, a French word like "leçon" woudl be split into "le" "çon", "le"
# is a stopword, we'd get "çon" and wouldn't find anything...
+#
foreach ( keys %{ C4::Context->stopwords } ) {
next if ( $_ =~ /(and|or|not)/ ); # don't remove operators
+ $debug && warn "$_ Dump($operand)";
if ( my ($matched) = ($operand =~
- /(\P{IsAlnum}\Q$_\E\P{IsAlnum}|^\Q$_\E\P{IsAlnum}|\P{IsAlnum}\Q$_\E$|^\Q$_\E$)/gi) )
+ /([^\X\p{isAlnum}]\Q$_\E[^\X\p{isAlnum}]|[^\X\p{isAlnum}]\Q$_\E$|^\Q$_\E[^\X\p{isAlnum}])/gi))
{
$operand =~ s/\Q$matched\E/ /gi;
push @stopwords_removed, $_;
@@ -996,9 +1001,10 @@ sub buildQuery {
# no stemming/weight/fuzzy in NoZebra
if ( C4::Context->preference("NoZebra") ) {
- $stemming = 0;
- $weight_fields = 0;
- $fuzzy_enabled = 0;
+ $stemming = 0;
+ $weight_fields = 0;
+ $fuzzy_enabled = 0;
+ $auto_truncation = 0;
}
my $query = $operands[0];
@@ -1016,10 +1022,10 @@ sub buildQuery {
my $stopwords_removed; # flag to determine if stopwords have been removed
my $cclq;
- my $indexes = getIndexes();
+ my $cclindexes = getIndexes();
if( $query !~ /\s*ccl=/ ){
- for my $index (@$indexes){
- if($query =~ /($index)(,?\w)*:/){
+ for my $index (@$cclindexes){
+ if($query =~ /($index)(,?\w)*[:=]/){
$cclq = 1;
}
}
@@ -1125,11 +1131,13 @@ sub buildQuery {
}
if ($auto_truncation){
- #FIXME only valid with LTR scripts
- $operand=join(" ",map{
- "$_*"
- }split (/\s+/,$operand));
- warn $operand if $DEBUG;
+ unless ( $index =~ /(st-|phr|ext)/ ) {
+ #FIXME only valid with LTR scripts
+ $operand=join(" ",map{
+ (index($_,"*")>0?"$_":"$_*")
+ }split (/\s+/,$operand));
+ warn $operand if $DEBUG;
+ }
}
# Detect Truncation
@@ -1392,16 +1400,20 @@ sub searchResults {
# We get the biblionumber position in MARC
my ($bibliotag,$bibliosubf)=GetMarcFromKohaField('biblio.biblionumber','');
- my $fw;
+ my $fw = '';
# loop through all of the records we've retrieved
for ( my $i = $offset ; $i <= $times - 1 ; $i++ ) {
my $marcrecord = MARC::File::USMARC::decode( $marcresults[$i] );
-
- if ($bibliotag<10){
- $fw = GetFrameworkCode($marcrecord->field($bibliotag)->data);
- }else{
- $fw = GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf));
+ my $biblionumber;
+
+ if(not $scan){
+ if ($bibliotag<10){
+ $biblionumber = $marcrecord->field($bibliotag) ? $marcrecord->field($bibliotag)->data : undef;
+ }else{
+ $biblionumber = $marcrecord->subfield($bibliotag,$bibliosubf);
+ }
+ $fw = (defined $biblionumber) ? GetFrameworkCode($biblionumber) : '';
}
my $oldbiblio = TransformMarcToKoha( $dbh, $marcrecord, $fw );
@@ -1428,33 +1440,49 @@ sub searchResults {
if ( $itemtypes{ $oldbiblio->{itemtype} }->{summary} ) {
my $summary = $itemtypes{ $oldbiblio->{itemtype} }->{summary};
my @fields = $marcrecord->fields();
- foreach my $field (@fields) {
- my $tag = $field->tag();
- my $tagvalue = $field->as_string();
- if (! utf8::is_utf8($tagvalue)) {
- utf8::decode($tagvalue);
+
+ my $newsummary;
+ foreach my $line ( "$summary\n" =~ /(.*)\n/g ){
+ my $tags = {};
+ foreach my $tag ( $line =~ /\[(\d{3}[\w|\d])\]/ ) {
+ $tag =~ /(.{3})(.)/;
+ if($marcrecord->field($1)){
+ my @abc = $marcrecord->field($1)->subfield($2);
+ $tags->{$tag} = $#abc + 1 ;
+ }
}
-
- $summary =~
- s/\[(.?.?.?.?)$tag\*(.*?)]/$1$tagvalue$2\[$1$tag$2]/g;
- unless ( $tag < 10 ) {
- my @subf = $field->subfields;
- for my $i ( 0 .. $#subf ) {
- my $subfieldcode = $subf[$i][0];
- my $subfieldvalue = $subf[$i][1];
- if (! utf8::is_utf8($subfieldvalue)) {
- utf8::decode($subfieldvalue);
+
+ # We catch how many times to repeat this line
+ my $max = 0;
+ foreach my $tag (keys(%$tags)){
+ $max = $tags->{$tag} if($tags->{$tag} > $max);
+ }
+
+ # we replace, and repeat each line
+ for (my $i = 0 ; $i < $max ; $i++){
+ my $newline = $line;
+
+ foreach my $tag ( $newline =~ /\[(\d{3}[\w|\d])\]/g ) {
+ $tag =~ /(.{3})(.)/;
+
+ if($marcrecord->field($1)){
+ my @repl = $marcrecord->field($1)->subfield($2);
+ my $subfieldvalue = $repl[$i];
+
+ if (! utf8::is_utf8($subfieldvalue)) {
+ utf8::decode($subfieldvalue);
+ }
+
+ $newline =~ s/\[$tag\]/$subfieldvalue/g;
}
- my $tagsubf = $tag . $subfieldcode;
- $summary =~
-s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g;
}
+ $newsummary .= "$newline\n";
}
}
- # FIXME: yuk
- $summary =~ s/\[(.*?)]//g;
- $summary =~ s/\n/
/g;
- $oldbiblio->{summary} = $summary;
+
+ $newsummary =~ s/\[(.*?)]//g;
+ $newsummary =~ s/\n/
/g;
+ $oldbiblio->{summary} = $newsummary;
}
# Pull out the items fields
@@ -1521,6 +1549,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g;
$onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber};
$onloan_items->{$key}->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $item->{itype} }->{imageurl} );
$onloan_items->{$key}->{barcode} = $item->{barcode};
+ $onloan_items->{$key}->{reserved} = $item->{reserved};
# if something's checked out and lost, mark it as 'long overdue'
if ( $item->{itemlost} ) {
$onloan_items->{$prefix}->{longoverdue}++;
@@ -1676,6 +1705,95 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g;
return @newresults;
}
+=head2 SearchAcquisitions
+ Search for acquisitions
+=cut
+
+sub SearchAcquisitions{
+ my ($datebegin, $dateend, $itemtypes,$criteria, $orderby) = @_;
+
+ my $dbh=C4::Context->dbh;
+ # Variable initialization
+ my $str=qq|
+ SELECT marcxml
+ FROM biblio
+ LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
+ LEFT JOIN items ON items.biblionumber=biblio.biblionumber
+ WHERE dateaccessioned BETWEEN ? AND ?
+ |;
+
+ my (@params,@loopcriteria);
+
+ push @params, $datebegin->output("iso");
+ push @params, $dateend->output("iso");
+
+ if (scalar(@$itemtypes)>0 and $criteria ne "itemtype" ){
+ if(C4::Context->preference("item-level_itypes")){
+ $str .= "AND items.itype IN (?".( ',?' x scalar @$itemtypes - 1 ).") ";
+ }else{
+ $str .= "AND biblioitems.itemtype IN (?".( ',?' x scalar @$itemtypes - 1 ).") ";
+ }
+ push @params, @$itemtypes;
+ }
+
+ if ($criteria =~/itemtype/){
+ if(C4::Context->preference("item-level_itypes")){
+ $str .= "AND items.itype=? ";
+ }else{
+ $str .= "AND biblioitems.itemtype=? ";
+ }
+
+ if(scalar(@$itemtypes) == 0){
+ my $itypes = GetItemTypes();
+ for my $key (keys %$itypes){
+ push @$itemtypes, $key;
+ }
+ }
+
+ @loopcriteria= @$itemtypes;
+ }elsif ($criteria=~/itemcallnumber/){
+ $str .= "AND (items.itemcallnumber LIKE CONCAT(?,'%')
+ OR items.itemcallnumber is NULL
+ OR items.itemcallnumber = '')";
+
+ @loopcriteria = ("AA".."ZZ", "") unless (scalar(@loopcriteria)>0);
+ }else {
+ $str .= "AND biblio.title LIKE CONCAT(?,'%') ";
+ @loopcriteria = ("A".."z") unless (scalar(@loopcriteria)>0);
+ }
+
+ if ($orderby =~ /date_desc/){
+ $str.=" ORDER BY dateaccessioned DESC";
+ } else {
+ $str.=" ORDER BY title";
+ }
+
+ my $qdataacquisitions=$dbh->prepare($str);
+
+ my @loopacquisitions;
+ foreach my $value(@loopcriteria){
+ push @params,$value;
+ my %cell;
+ $cell{"title"}=$value;
+ $cell{"titlecode"}=$value;
+
+ eval{$qdataacquisitions->execute(@params);};
+
+ if ($@){ warn "recentacquisitions Error :$@";}
+ else {
+ my @loopdata;
+ while (my $data=$qdataacquisitions->fetchrow_hashref){
+ push @loopdata, {"summary"=>GetBiblioSummary( $data->{'marcxml'} ) };
+ }
+ $cell{"loopdata"}=\@loopdata;
+ }
+ push @loopacquisitions,\%cell if (scalar(@{$cell{loopdata}})>0);
+ pop @params;
+ }
+ $qdataacquisitions->finish;
+ return \@loopacquisitions;
+}
+
#----------------------------------------------------------------------
#
# Non-Zebra GetRecords#
@@ -1905,7 +2023,7 @@ sub NZanalyse {
);
# split each word, query the DB and build the biblionumbers result
- foreach ( split / /, $string ) {
+ foreach ( split (/ /, $string )) {
next if C4::Context->stopwords->{ uc($_) }; # skip if stopword
warn "search on all indexes on $_" if $DEBUG;
my $biblionumbers;
@@ -1934,7 +2052,7 @@ sub NZanalyse {
sub NZoperatorAND{
my ($rightresult, $leftresult)=@_;
- my @leftresult = split /;/, $leftresult;
+ my @leftresult = split (/;/, $leftresult);
warn " @leftresult / $rightresult \n" if $DEBUG;
# my @rightresult = split /;/,$leftresult;
@@ -2008,8 +2126,8 @@ sub NZorder {
# popularity is not in MARC record, it's builded from a specific query
my $sth =
$dbh->prepare("select sum(issues) from items where biblionumber=?");
- foreach ( split /;/, $biblionumbers ) {
- my ( $biblionumber, $title ) = split /,/, $_;
+ foreach ( split (/;/, $biblionumbers )) {
+ my ( $biblionumber, $title ) = split (/,/, $_);
$result{$biblionumber} = GetMarcBiblio($biblionumber);
$sth->execute($biblionumber);
my $popularity = $sth->fetchrow || 0;
@@ -2048,8 +2166,8 @@ sub NZorder {
}
elsif ( $ordering =~ /author/ ) {
my %result;
- foreach ( split /;/, $biblionumbers ) {
- my ( $biblionumber, $title ) = split /,/, $_;
+ foreach ( split (/;/, $biblionumbers )) {
+ my ( $biblionumber, $title ) = split (/,/, $_);
my $record = GetMarcBiblio($biblionumber);
my $author;
if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
@@ -2091,8 +2209,8 @@ sub NZorder {
}
elsif ( $ordering =~ /callnumber/ ) {
my %result;
- foreach ( split /;/, $biblionumbers ) {
- my ( $biblionumber, $title ) = split /,/, $_;
+ foreach ( split (/;/, $biblionumbers )) {
+ my ( $biblionumber, $title ) = split (/,/, $_);
my $record = GetMarcBiblio($biblionumber);
my $callnumber;
my ( $callnumber_tag, $callnumber_subfield ) =
@@ -2134,8 +2252,8 @@ sub NZorder {
}
elsif ( $ordering =~ /pubdate/ ) { #pub year
my %result;
- foreach ( split /;/, $biblionumbers ) {
- my ( $biblionumber, $title ) = split /,/, $_;
+ foreach ( split (/;/, $biblionumbers )) {
+ my ( $biblionumber, $title ) = split (/,/, $_);
my $record = GetMarcBiblio($biblionumber);
my ( $publicationyear_tag, $publicationyear_subfield ) =
GetMarcFromKohaField( 'biblioitems.publicationyear', '' );
@@ -2176,8 +2294,8 @@ sub NZorder {
# the title is in the biblionumbers string, so we just need to build a hash, sort it and return
my %result;
- foreach ( split /;/, $biblionumbers ) {
- my ( $biblionumber, $title ) = split /,/, $_;
+ foreach ( split (/;/, $biblionumbers )) {
+ my ( $biblionumber, $title ) = split (/,/, $_);
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!