X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FVirtualShelves.pm;h=c74ecb3ef871473908658ec1dda0b70b48687973;hb=aa114f53499b9cffde0571fe7e08622f9c9a332a;hp=e5c8adc93fc739bbf3e9c95d809dade04e058bfe;hpb=39d2d593c6328f301874def20885883699028b48;p=koha_gimpoz diff --git a/C4/VirtualShelves.pm b/C4/VirtualShelves.pm index e5c8adc93f..c74ecb3ef8 100644 --- a/C4/VirtualShelves.pm +++ b/C4/VirtualShelves.pm @@ -17,16 +17,16 @@ package C4::VirtualShelves; # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along with -# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, -# Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; +use warnings; + use Carp; use C4::Context; -use C4::Circulation; use C4::Debug; -use C4::Members; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); @@ -36,17 +36,20 @@ BEGIN { require Exporter; @ISA = qw(Exporter); @EXPORT = qw( - &GetShelves &GetShelfContents &GetShelf - - &AddToShelf &AddToShelfFromBiblio &AddShelf - - &ModShelf - &ShelfPossibleAction - &DelFromShelf &DelShelf + &GetShelves &GetShelfContents &GetShelf + &AddToShelf &AddShelf + &ModShelf + &ShelfPossibleAction + &DelFromShelf &DelShelf + &GetBibliosShelves ); - @EXPORT_OK = qw(&GetShelvesSummary); + @EXPORT_OK = qw( + &GetShelvesSummary &GetRecentShelves &GetAllShelves + &RefreshShelvesSummary &SetShelvesLimit + ); } + my $dbh = C4::Context->dbh; =head1 NAME @@ -61,28 +64,23 @@ C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves This module provides functions for manipulating virtual virtualshelves, including creating and deleting virtualshelves, and adding and removing -items to and from virtualshelves. +bibs to and from virtualshelves. =head1 FUNCTIONS -=over 2 - -=item GetShelves +=head2 GetShelves - $shelflist = &GetShelves($owner); - $shelflist = &GetShelves($owner, $mincategory); - $shelflist = &GetShelves($owner, $mincategory, $limit); + ($shelflist, $totshelves) = &GetShelves($mincategory, $row_count, $offset, $owner); ($shelfnumber, $shelfhash) = each %{$shelflist}; -Looks up the virtual virtualshelves, and returns a summary. C<$shelflist> -is a reference-to-hash. The keys are the virtualshelves numbers -(C<$shelfnumber>, above), and the values (C<$shelfhash>, above) are -themselves references-to-hash, with the following keys: +Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total +number of shelves that meet the C<$owner> and C<$mincategory> criteria. C<$mincategory>, +C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1. +When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>. +C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above), +and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys: -C : 2 if the list is for "Public", 3 for "Open". -virtualshelves of the owner are always selected, whatever the category - -=over 4 +=over =item C<$shelfhash-E{shelfname}> @@ -96,48 +94,66 @@ The number of virtuals on that virtualshelves. =cut -sub GetShelves { - my ($owner, $mincategory, $limit) = @_; - ($mincategory and $mincategory =~ /^\d+$/) or $mincategory = 2; - ( $limit and $limit =~ /^\d+$/) or $limit = undef; +sub GetShelves ($$$$) { + my ($mincategory, $row_count, $offset, $owner) = @_; + my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count); + my @params1 = ($owner, $mincategory); + if ($mincategory > 1) { + shift @params; + shift @params1; + } + my $total = _shelf_count($owner, $mincategory); + # grab only the shelves meeting the row_count/offset spec... my $query = qq( SELECT virtualshelves.shelfnumber, virtualshelves.shelfname,owner,surname,firstname,virtualshelves.category,virtualshelves.sortfield, count(virtualshelfcontents.biblionumber) as count FROM virtualshelves LEFT JOIN virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber - LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber - WHERE owner=? OR category>=? + LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber ); + $query .= ($mincategory == 1) ? "WHERE owner=? AND category=?" : "WHERE category>=?"; + $query .= qq( GROUP BY virtualshelves.shelfnumber - ORDER BY virtualshelves.category, virtualshelves.shelfname, borrowers.firstname, borrowers.surname - ); - $limit and $query .= " LIMIT $limit "; - my $sth = $dbh->prepare($query); - $sth->execute( $owner, $mincategory ); + ORDER BY virtualshelves.shelfname + LIMIT ?, ?); + my $sth2 = $dbh->prepare($query); + $sth2->execute(@params); my %shelflist; - while ( - my ( - $shelfnumber, $shelfname, $owner, $surname, - $firstname, $category, $sortfield, $count - ) - = $sth->fetchrow - ) - { + while ( my ( $shelfnumber, $shelfname, $owner, $surname, + $firstname, $category, $sortfield, $count ) = $sth2->fetchrow ) { $shelflist{$shelfnumber}->{'shelfname'} = $shelfname; $shelflist{$shelfnumber}->{'count'} = $count; + if($count eq 1){ $shelflist{$shelfnumber}->{'single'} = 1; } $shelflist{$shelfnumber}->{'sortfield'} = $sortfield; $shelflist{$shelfnumber}->{'category'} = $category; $shelflist{$shelfnumber}->{'owner'} = $owner; $shelflist{$shelfnumber}->{'surname'} = $surname; $shelflist{$shelfnumber}->{'firstname'} = $firstname; } - return ( \%shelflist ); + return ( \%shelflist, $total ); } -sub GetShelvesSummary { - my ($owner, $mincategory, $limit) = @_; - ($mincategory and $mincategory =~ /^\d+$/) or $mincategory = 2; - ( $limit and $limit =~ /^\d+$/) or $limit = 10; - my $query = qq( +=head2 GetShelvesSummary + + ($shelves, $total) = GetShelvesSummary($mincategory, $row_count, $offset, $owner) + +Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total +number of shelves that meet the C<$owner> and/or C<$mincategory> criteria. C<$mincategory>, +C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1. +When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>. + +=cut + +sub GetShelvesSummary ($$$$) { + my ($mincategory, $row_count, $offset, $owner) = @_; + my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count); + my @params1 = ($owner, $mincategory); + if ($mincategory > 1) { + shift @params; + shift @params1; + } + my $total = _shelf_count($owner, $mincategory); + # grab only the shelves meeting the row_count/offset spec... + my $query = qq( SELECT virtualshelves.shelfnumber, virtualshelves.shelfname, @@ -147,25 +163,17 @@ sub GetShelvesSummary { count(virtualshelfcontents.biblionumber) AS count FROM virtualshelves LEFT JOIN virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber - LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber - WHERE owner=? OR category>=? + LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber ); + $query .= ($mincategory == 1) ? "WHERE owner=? AND category=?" : "WHERE category>=?"; + $query .= qq( GROUP BY virtualshelves.shelfnumber - ORDER BY virtualshelves.category, borrowers.surname, borrowers.firstname, virtualshelves.shelfname - LIMIT ? - ); - my $sth = $dbh->prepare($query); - $sth->execute($owner,$mincategory,$limit); - - my $shelves = $sth->fetchall_arrayref({}); - # add private flag to each shelf entry -- - # need to do this because HTML::Template::Pro's EXPR - # support complains about a non-initialized 'category' - # if the user has no shelves -- the offending line in - # masthead.inc was <-- TMPL_IF EXPR="category == 1"... - foreach my $shelf (@{ $shelves }) { - $shelf->{'private'} = ($shelf->{'category'} == 1); - } - return $shelves; + ORDER BY virtualshelves.category + DESC + LIMIT ?, ?); + my $sth2 = $dbh->prepare($query); + $sth2->execute(@params); + my $shelves = $sth2->fetchall_arrayref({}); + return ($shelves, $total); # Probably NOT the final implementation since it is still bulky (repeated hash keys). # might like an array of rows of delimited values: @@ -173,7 +181,65 @@ sub GetShelvesSummary { # 2|6|Josh Ferraro|51|en_fuego|106 } -=item GetShelf +=head2 GetRecentShelves + + ($shelflist, $total) = GetRecentShelves(1, $limit, $owner) + +This function returns a reference to an array of hashrefs containing specified shelves sorted +by the date the shelf was last modified in descending order limited to the number of records +specified by C<$row_count>. If calling with C<$mincategory> other than 1, use undef as C<$owner>. + +This function is intended to return a dataset reflecting the most recently active shelves for +the submitted parameters. + +=cut + +sub GetRecentShelves { + my ($mincategory, $row_count, $owner) = @_; + my $total = _shelf_count($owner, $mincategory); + my @params; + my $selection; + if (defined $owner) { + @params = ($owner, $mincategory); + $selection = ' WHERE owner = ? AND category = ?'; + } else { + @params = ( $mincategory); + $selection = ' WHERE category >= ? '; + } + my $query = 'SELECT * FROM virtualshelves'; + $query .= $selection; + $query .= ' ORDER BY lastmodified DESC'; + if ($row_count){ + $query .= ' LIMIT ?'; + push @params,$row_count; + } + my $sth = $dbh->prepare($query); + $sth->execute(@params); + my $shelflist = $sth->fetchall_arrayref({}); + return ( $shelflist, $total ); +} + +=head2 GetAllShelves + + $shelflist = GetAllShelves($owner) + +This function returns a reference to an array of hashrefs containing all shelves sorted +by the shelf name. + +This function is intended to return a dataset reflecting all the shelves for +the submitted parameters. + +=cut + +sub GetAllShelves { + my ($category,$owner) = @_; + my $query = 'SELECT * FROM virtualshelves WHERE category = ? AND owner = ? ORDER BY shelfname ASC'; + my $sth = $dbh->prepare( $query ); + $sth->execute( $category, $owner ); + return $sth->fetchall_arrayref({}); +} + +=head2 GetShelf (shelfnumber,shelfname,owner,category,sortfield) = &GetShelf($shelfnumber); @@ -184,7 +250,7 @@ Returns the database's information on 'virtualshelves' table. =cut -sub GetShelf { +sub GetShelf ($) { my ($shelfnumber) = @_; my $query = qq( SELECT shelfnumber, shelfname, owner, category, sortfield @@ -196,9 +262,9 @@ sub GetShelf { return $sth->fetchrow; } -=item GetShelfContents +=head2 GetShelfContents - $itemlist = &GetShelfContents($shelfnumber); + $biblist = &GetShelfContents($shelfnumber); Looks up information about the contents of virtual virtualshelves number C<$shelfnumber>. Sorted by a field in the biblio table. copyrightdate @@ -214,29 +280,38 @@ from C4::Circulation. =cut -sub GetShelfContents { - my ( $shelfnumber ,$sortfield) = @_; +sub GetShelfContents ($;$$$) { + my ($shelfnumber, $row_count, $offset, $sortfield) = @_; my $dbh=C4::Context->dbh(); + my $sth1 = $dbh->prepare("SELECT count(*) FROM virtualshelfcontents WHERE shelfnumber = ?"); + $sth1->execute($shelfnumber); + my $total = $sth1->fetchrow; if(!$sortfield) { - my $sthsort = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?'); - $sthsort->execute($shelfnumber); - ($sortfield) = $sthsort->fetchrow_array; + my $sth2 = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?'); + $sth2->execute($shelfnumber); + ($sortfield) = $sth2->fetchrow_array; } my $query = - " SELECT vc.biblionumber, vc.shelfnumber, vc.dateadded, - biblio.*, biblioitems.itemtype, itemtypes.* + " SELECT vc.biblionumber, vc.shelfnumber, vc.dateadded, itemtypes.*, + biblio.*, biblioitems.itemtype, biblioitems.publicationyear as year, biblioitems.publishercode, biblioitems.place, biblioitems.size, biblioitems.pages FROM virtualshelfcontents vc LEFT JOIN biblio ON vc.biblionumber = biblio.biblionumber LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype WHERE vc.shelfnumber=? "; + my @params = ($shelfnumber); if($sortfield) { - $query .= " ORDER BY `$sortfield` "; + $query .= " ORDER BY " . $sortfield; $query .= " DESC " if ($sortfield eq 'copyrightdate'); } - my $sth = $dbh->prepare($query); - $sth->execute($shelfnumber); - return $sth->fetchall_arrayref({}); + if($row_count){ + $query .= " LIMIT ?, ? "; + push (@params, ($offset ? $offset : 0)); + push (@params, $row_count); + } + my $sth3 = $dbh->prepare($query); + $sth3->execute(@params); + return ($sth3->fetchall_arrayref({}), $total); # Like the perldoc says, # returns reference-to-array, where each element is reference-to-hash of the row: # like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ] @@ -245,7 +320,7 @@ sub GetShelfContents { # or newer, for your version of DBI. } -=item AddShelf +=head2 AddShelf $shelfnumber = &AddShelf( $shelfname, $owner, $category); @@ -259,7 +334,7 @@ Returns a code to know what's happen. =cut sub AddShelf { - my ( $shelfname, $owner, $category ) = @_; + my ( $shelfname, $owner, $category, $sortfield ) = @_; my $query = qq( SELECT * FROM virtualshelves @@ -270,21 +345,21 @@ sub AddShelf { ( $sth->rows ) and return (-1); $query = qq( INSERT INTO virtualshelves - (shelfname,owner,category) - VALUES (?,?,?) + (shelfname,owner,category,sortfield) + VALUES (?,?,?,?) ); $sth = $dbh->prepare($query); - $sth->execute( $shelfname, $owner, $category ); + $sth->execute( $shelfname, $owner, $category, $sortfield ); my $shelfnumber = $dbh->{'mysql_insertid'}; return ($shelfnumber); } -=item AddToShelf +=head2 AddToShelf &AddToShelf($biblionumber, $shelfnumber); -Adds item number C<$biblionumber> to virtual virtualshelves number -C<$shelfnumber>, unless that item is already on that shelf. +Adds bib number C<$biblionumber> to virtual virtualshelves number +C<$shelfnumber>, unless that bib is already on that shelf. =cut @@ -309,40 +384,14 @@ sub AddToShelf { ); $sth = $dbh->prepare($query); $sth->execute( $shelfnumber, $biblionumber ); + $query = qq(UPDATE virtualshelves + SET lastmodified = CURRENT_TIMESTAMP + WHERE shelfnumber = ?); + $sth = $dbh->prepare($query); + $sth->execute( $shelfnumber ); } -=item AddToShelfFromBiblio - - &AddToShelfFromBiblio($biblionumber, $shelfnumber) - - this function allow to add a virtual into the shelf number $shelfnumber - from biblionumber. - -=cut - -sub AddToShelfFromBiblio { - my ( $biblionumber, $shelfnumber ) = @_; - return unless $biblionumber; - my $query = qq( - SELECT * - FROM virtualshelfcontents - WHERE shelfnumber=? AND biblionumber=? - ); - my $sth = $dbh->prepare($query); - $sth->execute( $shelfnumber, $biblionumber ); - unless ( $sth->rows ) { - my $query =qq( - INSERT INTO virtualshelfcontents - (shelfnumber, biblionumber, flags) - VALUES - (?, ?, 0) - ); - $sth = $dbh->prepare($query); - $sth->execute( $shelfnumber, $biblionumber ); - } -} - -=item ModShelf +=head2 ModShelf ModShelf($shelfnumber, $hashref) @@ -391,7 +440,7 @@ sub ModShelf { $sth->execute( @bind_params ); } -=item ShelfPossibleAction +=head2 ShelfPossibleAction ShelfPossibleAction($loggedinuser, $shelfnumber, $action); @@ -414,21 +463,23 @@ sub ShelfPossibleAction { my $sth = $dbh->prepare($query); $sth->execute($shelfnumber); my ( $owner, $category ) = $sth->fetchrow; - my $borrower = GetMemberDetails($user); + require C4::Members; + my $borrower = C4::Members::GetMemberDetails($user); + return 0 if not defined($user); return 1 if ( $category >= 3); # open list return 1 if (($category >= 2) and defined($action) and $action eq 'view'); # public list, anybody can view - return 1 if (($category >= 2) and defined($user) and $borrower->{authflags}->{superlibrarian}); # public list, superlibrarian can edit/delete + return 1 if (($category >= 2) and defined($user) and ($borrower->{authflags}->{superlibrarian} || $user == 0)); # public list, superlibrarian can edit/delete return 1 if (defined($user) and $owner eq $user ); # user owns this list. Check last. return 0; } -=item DelFromShelf +=head2 DelFromShelf &DelFromShelf( $biblionumber, $shelfnumber); -Removes item number C<$biblionumber> from virtual virtualshelves number -C<$shelfnumber>. If the item wasn't on that virtualshelves to begin with, +Removes bib number C<$biblionumber> from virtual virtualshelves number +C<$shelfnumber>. If the bib wasn't on that virtualshelves to begin with, nothing happens. =cut @@ -444,7 +495,7 @@ sub DelFromShelf { $sth->execute( $shelfnumber, $biblionumber ); } -=item DelShelf (old version) +=head2 DelShelf (old version) ($status, $msg) = &DelShelf($shelfnumber); @@ -455,7 +506,7 @@ Returns a two-element array, where C<$status> is 0 if the operation was successful, or non-zero otherwise. C<$msg> is "Done" in case of success, or an error message giving the reason for failure. -=item DelShelf (current version) +=head2 DelShelf (current version) $Number = DelShelf($shelfnumber); @@ -472,15 +523,104 @@ sub DelShelf { return $sth->execute(shift); } +=head2 GetBibShelves + +This finds all the public lists that this bib record is in. + +=cut + +sub GetBibliosShelves { + my ( $biblionumber ) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare(' + SELECT vs.shelfname, vs.shelfnumber + FROM virtualshelves vs + JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber) + WHERE vs.category != 1 + AND vc.biblionumber= ? + '); + $sth->execute( $biblionumber ); + return $sth->fetchall_arrayref({}); +} + +=head2 RefreshShelvesSummary + + ($total, $pubshelves, $barshelves) = RefreshShelvesSummary($sessionID, $loggedinuser, $row_count); + +Updates the current session and userenv with the most recent shelves + +Returns the total number of shelves stored in the session/userenv along with two references each to an +array of hashes, one containing the C<$loggedinuser>'s private shelves and one containing all public/open shelves. + +This function is used in conjunction with the 'Lists' button in masthead.inc. + +=cut + +sub RefreshShelvesSummary ($$$) { + require C4::Auth; + my ($sessionID, $loggedinuser, $row_count) = @_; + my $session = C4::Auth::get_session($sessionID); + my ($total, $totshelves, $barshelves, $pubshelves); + + ($barshelves, $totshelves) = GetRecentShelves(1, $row_count, $loggedinuser); + $total->{'bartotal'} = $totshelves; + ($pubshelves, $totshelves) = GetRecentShelves(2, $row_count, undef); + $total->{'pubtotal'} = $totshelves; + + # Update the current session with the latest shelves... + $session->param('barshelves', $barshelves); + $session->param('pubshelves', $pubshelves); + $session->param('totshelves', $total); + + # likewise the userenv... + C4::Context->set_shelves_userenv('bar',$barshelves); + C4::Context->set_shelves_userenv('pub',$pubshelves); + C4::Context::set_shelves_userenv('tot',$total); + + return ($total, $pubshelves, $barshelves); +} + +# internal subs + +sub _shelf_count ($$) { + my (@params) = @_; + # Find out how many shelves total meet the submitted criteria... + my $query = "SELECT count(*) FROM virtualshelves"; + $query .= ($params[1] > 1) ? " WHERE category >= ?" : " WHERE owner=? AND category=?"; + shift @params if $params[1] > 1; + my $sth = $dbh->prepare($query); + $sth->execute(@params); + my $total = $sth->fetchrow; + return $total; +} + +sub _biblionumber_sth { + my ($shelf) = @_; + my $query = 'select biblionumber from virtualshelfcontents where shelfnumber = ?'; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query) + or die $dbh->errstr; + $sth->execute( $shelf ) + or die $sth->errstr; + $sth; +} + +sub each_biblionumbers (&$) { + my ($code,$shelf) = @_; + my $ref = _biblionumber_sth($shelf)->fetchall_arrayref; + map { + $_=$$_[0]; + $code->(); + } @$ref; +} + 1; __END__ -=back - =head1 AUTHOR -Koha Developement team +Koha Development Team =head1 SEE ALSO