@@ -, +, @@ --- C4/Auth.pm | 61 +-- C4/VirtualShelves.pm | 577 +++++++++++--------- C4/VirtualShelves/Page.pm | 143 +++-- catalogue/search.pl | 26 +- .../en/modules/virtualshelves/addbybiblionumber.tt | 36 +- .../prog/en/modules/virtualshelves/shelves.tt | 28 +- koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc | 28 +- .../prog/en/modules/opac-addbybiblionumber.tt | 11 +- .../opac-tmpl/prog/en/modules/opac-shelves.tt | 26 +- opac/opac-addbybiblionumber.pl | 186 ++++--- opac/opac-search.pl | 27 +- opac/opac-shelves.pl | 8 +- virtualshelves/addbybiblionumber.pl | 243 ++++----- 13 files changed, 728 insertions(+), 672 deletions(-) --- a/C4/Auth.pm +++ a/C4/Auth.pm @@ -162,21 +162,15 @@ sub get_template_and_user { $template->param( loggedinusername => $user ); $template->param( sessionID => $sessionID ); - my ($total, $pubshelves, $barshelves) = C4::Context->get_shelves_userenv(); - if (defined($pubshelves)) { - $template->param( pubshelves => scalar @{$pubshelves}, - pubshelvesloop => $pubshelves, - ); - $template->param( pubtotal => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar @{$pubshelves}); - } - if (defined($barshelves)) { - $template->param( barshelves => scalar @{$barshelves}, - barshelvesloop => $barshelves, - ); - $template->param( bartotal => $total->{'bartotal'}, ) if ($total->{'bartotal'} > scalar @{$barshelves}); - } - $borrowernumber = getborrowernumber($user) if defined($user); + my ($total, $pubshelves, $barshelves) = C4::VirtualShelves::GetSomeShelfNames($borrowernumber, 'MASTHEAD'); + $template->param( + pubshelves => $total->{pubtotal}, + pubshelvesloop => $pubshelves, + barshelves => $total->{bartotal}, + barshelvesloop => $barshelves, + ); + require C4::Members; my ( $borr ) = C4::Members::GetMemberDetails( $borrowernumber ); my @bordat; @@ -294,14 +288,11 @@ sub get_template_and_user { $template->param( sessionID => $sessionID ); - my ($total, $pubshelves) = C4::Context->get_shelves_userenv(); # an anonymous user has no 'barshelves'... - if (defined $pubshelves) { - $template->param( pubshelves => scalar @{$pubshelves}, - pubshelvesloop => $pubshelves, - ); - $template->param( pubtotal => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar @{$pubshelves}); - } - + my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD'); + $template->param( + pubshelves => $total->{pubtotal}, + pubshelvesloop => $pubshelves, + ); } # Anonymous opac search history # If opac search history is enabled and at least one search has already been performed @@ -870,22 +861,6 @@ sub checkauth { $session->param('emailaddress'), $session->param('branchprinter') ); - # Grab borrower's shelves and public shelves and add them to the session - # $row_count determines how many records are returned from the db query - # and the number of lists to be displayed of each type in the 'Lists' button drop down - my $row_count = 10; # FIXME:This probably should be a syspref - my ($total, $totshelves, $barshelves, $pubshelves); - ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $borrowernumber); - $total->{'bartotal'} = $totshelves; - ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef); - $total->{'pubtotal'} = $totshelves; - $session->param('barshelves', $barshelves); - $session->param('pubshelves', $pubshelves); - $session->param('totshelves', $total); - - C4::Context::set_shelves_userenv('bar',$barshelves); - C4::Context::set_shelves_userenv('pub',$pubshelves); - C4::Context::set_shelves_userenv('tot',$total); } else { if ($userid) { @@ -899,16 +874,6 @@ sub checkauth { # anonymous sessions are created only for the OPAC $debug and warn "Initiating an anonymous session..."; - # Grab the public shelves and add to the session... - my $row_count = 20; # FIXME:This probably should be a syspref - my ($total, $totshelves, $pubshelves); - ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef); - $total->{'pubtotal'} = $totshelves; - $session->param('pubshelves', $pubshelves); - $session->param('totshelves', $total); - C4::Context::set_shelves_userenv('pub',$pubshelves); - C4::Context::set_shelves_userenv('tot',$total); - # setting a couple of other session vars... $session->param('ip',$session->remote_addr()); $session->param('lasttime',time()); --- a/C4/VirtualShelves.pm +++ a/C4/VirtualShelves.pm @@ -28,6 +28,11 @@ use Carp; use C4::Context; use C4::Debug; +use constant SHELVES_MASTHEAD_MAX => 10; #number under Lists button in masthead +use constant SHELVES_COMBO_MAX => 10; #add to combo in search +use constant SHELVES_MGRPAGE_MAX => 20; #managing page +use constant SHELVES_POPUP_MAX => 40; #addbybiblio popup + use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); BEGIN { @@ -44,8 +49,7 @@ BEGIN { &GetBibliosShelves ); @EXPORT_OK = qw( - &GetShelvesSummary &GetRecentShelves &GetAllShelves - &RefreshShelvesSummary &SetShelvesLimit + &GetAllShelves &ShelvesMax ); } @@ -54,7 +58,7 @@ my $dbh = C4::Context->dbh; =head1 NAME -C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves +C4::VirtualShelves - Functions for manipulating Koha virtual shelves =head1 SYNOPSIS @@ -62,21 +66,24 @@ C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves =head1 DESCRIPTION -This module provides functions for manipulating virtual virtualshelves, -including creating and deleting virtualshelves, and adding and removing -bibs to and from virtualshelves. +This module provides functions for manipulating virtual shelves, +including creating and deleting virtual shelves, and adding and removing +bibs to and from virtual shelves. =head1 FUNCTIONS =head2 GetShelves - ($shelflist, $totshelves) = &GetShelves($mincategory, $row_count, $offset, $owner); + ($shelflist, $totshelves) = &GetShelves($category, $row_count, $offset, $owner); ($shelfnumber, $shelfhash) = each %{$shelflist}; 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>. +number of shelves that meet the C<$owner> and C<$category> criteria. C<$category>, +C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$category> == 1. +When C<$category> is 2, supply undef as argument for C<$owner>. + +This function is used by shelfpage in VirtualShelves/Page.pm when listing all shelves for lists management in opac or staff client. Order is by shelfname. + 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: @@ -94,35 +101,40 @@ The number of virtuals on that virtualshelves. =cut -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 ); - $query .= ($mincategory == 1) ? "WHERE owner=? AND category=?" : "WHERE category>=?"; - $query .= qq( - GROUP BY virtualshelves.shelfnumber - ORDER BY virtualshelves.shelfname - LIMIT ?, ?); +sub GetShelves { + my ($category, $row_count, $offset, $owner) = @_; + my @params; + my $total = _shelf_count($owner, $category); + my $query = qq{ + SELECT vs.shelfnumber, vs.shelfname,vs.owner, + bo.surname,bo.firstname,vs.category,vs.sortfield, + count(vc.biblionumber) as count + FROM virtualshelves vs + LEFT JOIN borrowers bo ON vs.owner=bo.borrowernumber + LEFT JOIN virtualshelfcontents vc USING (shelfnumber) }; + if($category==1) { + $query.= qq{ + LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber + AND sh.borrowernumber=? + WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; + @params= ($owner, $owner, $owner, $offset||0, $row_count); + } + else { + $query.= 'WHERE category=2 '; + @params= ($offset||0, $row_count); + } + $query.= qq{ + GROUP BY vs.shelfnumber + ORDER BY vs.shelfname + LIMIT ?, ?}; + my $sth2 = $dbh->prepare($query); $sth2->execute(@params); my %shelflist; - while ( my ( $shelfnumber, $shelfname, $owner, $surname, - $firstname, $category, $sortfield, $count ) = $sth2->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}->{'single'} = $count==1; $shelflist{$shelfnumber}->{'sortfield'} = $sortfield; $shelflist{$shelfnumber}->{'category'} = $category; $shelflist{$shelfnumber}->{'owner'} = $owner; @@ -132,111 +144,77 @@ sub GetShelves ($$$$) { return ( \%shelflist, $total ); } -=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, - owner, - CONCAT(firstname, ' ', surname) AS name, - virtualshelves.category, - count(virtualshelfcontents.biblionumber) AS count - FROM virtualshelves - LEFT JOIN virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber - 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 - 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: - # 1|2||0|blacklist|112 - # 2|6|Josh Ferraro|51|en_fuego|106 -} - -=head2 GetRecentShelves +=head2 GetAllShelves - ($shelflist, $total) = GetRecentShelves(1, $limit, $owner) + $shelflist = GetAllShelves($category, $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 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 the most recently active shelves for +This function is intended to return a dataset reflecting all the shelves for the submitted parameters. =cut -sub GetRecentShelves { - my ($mincategory, $row_count, $owner) = @_; - my $total = _shelf_count($owner, $mincategory); +sub GetAllShelves { + my ($category,$owner,$adding_allowed) = @_; my @params; - my $selection; - if (defined $owner) { - @params = ($owner, $mincategory); - $selection = ' WHERE owner = ? AND category = ?'; - } else { - @params = ( $mincategory); - $selection = ' WHERE category >= ? '; + my $query = 'SELECT vs.* FROM virtualshelves vs '; + if($category==1) { + $query.= qq{ + LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber + AND sh.borrowernumber=? + WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; + @params = ($owner, $owner, $owner); } - my $query = 'SELECT * FROM virtualshelves'; - $query .= $selection; - $query .= ' ORDER BY lastmodified DESC'; - if ($row_count){ - $query .= ' LIMIT ?'; - push @params,$row_count; + else { + $query.='WHERE category=2 '; + @params = (); } - my $sth = $dbh->prepare($query); + $query.='AND (allow_add=1 OR owner=?) ' if $adding_allowed; + push @params, $owner if $adding_allowed; + $query.= 'ORDER BY shelfname ASC'; + my $sth = $dbh->prepare( $query ); $sth->execute(@params); - my $shelflist = $sth->fetchall_arrayref({}); - return ( $shelflist, $total ); + return $sth->fetchall_arrayref({}); } -=head2 GetAllShelves +=head2 GetSomeShelfNames - $shelflist = GetAllShelves($owner) +Returns shelf names and numbers for Add to combo of search results and Lists button of OPAC header. -This function returns a reference to an array of hashrefs containing all shelves sorted -by the shelf name. +=cut -This function is intended to return a dataset reflecting all the shelves for -the submitted parameters. +sub GetSomeShelfNames { + my ($owner, $purpose, $adding_allowed)= @_; + my ($bar, $pub, @params); -=cut + my $bquery = 'SELECT vs.shelfnumber, vs.shelfname FROM virtualshelves vs '; + my $limit= ShelvesMax($purpose); -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({}); + my $qry1= $bquery."WHERE vs.category=2 "; + $qry1.= "AND (allow_add=1 OR owner=?) " if $adding_allowed; + push @params, $owner||0 if $adding_allowed; + $qry1.= "ORDER BY vs.lastmodified DESC LIMIT $limit"; + + unless($adding_allowed && (!defined($owner) || $owner<=0)) { + #if adding items, user should be known + $pub= $dbh->selectall_arrayref($qry1,{Slice=>{}},@params); + } + + if($owner) { + my $qry2= $bquery. qq{ + LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber AND sh.borrowernumber=? + WHERE vs.category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; + @params=($owner,$owner,$owner); + $qry2.= "AND (allow_add=1 OR owner=?) " if $adding_allowed; + push @params, $owner if $adding_allowed; + $qry2.= "ORDER BY vs.lastmodified DESC "; + $qry2.= "LIMIT $limit"; + $bar= $dbh->selectall_arrayref($qry2,{Slice=>{}},@params); + } + + return ( { bartotal => $bar? scalar @$bar: 0, pubtotal => $pub? scalar @$pub: 0}, $pub, $bar); } =head2 GetShelf @@ -322,50 +300,54 @@ sub GetShelfContents ($;$$$) { =head2 AddShelf - $shelfnumber = &AddShelf( $shelfname, $owner, $category); + $shelfnumber = &AddShelf($hashref, $owner); -Creates a new virtual virtualshelves with name C<$shelfname>, owner C<$owner> and category -C<$category>. +Creates a new virtual shelf. Params passed in a hash like ModShelf. Returns a code to know what's happen. - * -1 : if this virtualshelves already exist. + * -1 : if this virtualshelves already exists. * $shelfnumber : if success. =cut sub AddShelf { - my ( $shelfname, $owner, $category, $sortfield ) = @_; - my $query = qq( - SELECT * - FROM virtualshelves - WHERE shelfname=? AND owner=? - ); + my ($hashref, $owner)= @_; + + #initialize missing hash values to silence warnings + foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) { + $hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': ''; + } + + return -1 unless _CheckShelfName($hashref->{shelfname}, $hashref->{category}, $owner, 0); + + my $query = qq(INSERT INTO virtualshelves + (shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other) + VALUES (?,?,?,?,?,?,?)); + my $sth = $dbh->prepare($query); - $sth->execute($shelfname,$owner); - ( $sth->rows ) and return (-1); - $query = qq( - INSERT INTO virtualshelves - (shelfname,owner,category,sortfield) - VALUES (?,?,?,?) - ); - $sth = $dbh->prepare($query); - $sth->execute( $shelfname, $owner, $category, $sortfield ); + $sth->execute( + $hashref->{shelfname}, + $owner, + $hashref->{category}, + $hashref->{sortfield}, + $hashref->{allow_add}||0, + $hashref->{allow_delete_own}||1, + $hashref->{allow_delete_other}||0 ); my $shelfnumber = $dbh->{'mysql_insertid'}; - return ($shelfnumber); + return $shelfnumber; } =head2 AddToShelf - &AddToShelf($biblionumber, $shelfnumber); + &AddToShelf($biblionumber, $shelfnumber, $borrower); Adds bib number C<$biblionumber> to virtual virtualshelves number C<$shelfnumber>, unless that bib is already on that shelf. =cut -#' sub AddToShelf { - my ( $biblionumber, $shelfnumber ) = @_; + my ($biblionumber, $shelfnumber, $borrowernumber) = @_; return unless $biblionumber; my $query = qq( SELECT * @@ -378,12 +360,10 @@ sub AddToShelf { ($sth->rows) and return undef; # already on shelf $query = qq( INSERT INTO virtualshelfcontents - (shelfnumber, biblionumber, flags) - VALUES - (?, ?, 0) - ); + (shelfnumber, biblionumber, flags, borrowernumber) + VALUES (?, ?, 0, ?)); $sth = $dbh->prepare($query); - $sth->execute( $shelfnumber, $biblionumber ); + $sth->execute( $shelfnumber, $biblionumber, $borrowernumber); $query = qq(UPDATE virtualshelves SET lastmodified = CURRENT_TIMESTAMP WHERE shelfnumber = ?); @@ -393,51 +373,55 @@ sub AddToShelf { =head2 ModShelf -ModShelf($shelfnumber, $hashref) +my $result= ModShelf($shelfnumber, $hashref) Where $hashref->{column} = param Modify the value into virtualshelves table with values given from hashref, which each key of the hashref should be the name of a column of virtualshelves. +Fields like shelfnumber or owner cannot be changed. + +Returns 1 if the action seemed to be successful. =cut sub ModShelf { - my $shelfnumber = shift; - my $shelf = shift; - - if (exists $shelf->{shelfnumber}) { - carp "Should not use ModShelf to change shelfnumber"; - return; - } - unless (defined $shelfnumber and $shelfnumber =~ /^\d+$/) { - carp "Invalid shelfnumber passed to ModShelf: $shelfnumber"; - return; - } + my ($shelfnumber,$hashref) = @_; - my $query = "UPDATE virtualshelves SET "; - my @bind_params = (); - my @set_clauses = (); + my $query= "SELECT * FROM virtualshelves WHERE shelfnumber=?"; + my $sth = $dbh->prepare($query); + $sth->execute($shelfnumber); + my $oldrecord= $sth->fetchrow_hashref; + return 0 unless $oldrecord; #not found? - foreach my $column (keys %$shelf) { - push @set_clauses, "$column = ?"; - push @bind_params, $shelf->{$column}; + #initialize missing hash values to silence warnings + foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) { + $hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': ''; } - if ($#set_clauses == -1) { - carp "No columns to update passed to ModShelf"; - return; + #if name or category changes, the name should be tested + if($hashref->{shelfname} || $hashref->{category}) { + unless(_CheckShelfName( + $hashref->{shelfname}||$oldrecord->{shelfname}, + $hashref->{category}||$oldrecord->{category}, + $oldrecord->{owner}, $shelfnumber )) { + return 0; #name check failed + } } - $query .= join(", ", @set_clauses); - - $query .= " WHERE shelfnumber = ? "; - push @bind_params, $shelfnumber; - $debug and warn "ModShelf query:\n $query\n", - "ModShelf query args: ", join(',', @bind_params), "\n"; - my $sth = $dbh->prepare($query); - $sth->execute( @bind_params ); + #only the following fields from the hash may be changed + $query= "UPDATE virtualshelves SET shelfname=?, category=?, sortfield=?, allow_add=?, allow_delete_own=?, allow_delete_other=? WHERE shelfnumber=?"; + $sth = $dbh->prepare($query); + $sth->execute( + $hashref->{shelfname}||$oldrecord->{shelfname}, + $hashref->{category}||$oldrecord->{category}, + $hashref->{sortfield}||$oldrecord->{sortfield}, + $hashref->{allow_add}||$oldrecord->{allow_add}, + $hashref->{allow_delete_own}||$oldrecord->{allow_delete_own}, + $hashref->{allow_delete_other}||$oldrecord->{allow_delete_other}, + $shelfnumber ); + return $@? 0: 1; } =head2 ShelfPossibleAction @@ -446,7 +430,11 @@ ShelfPossibleAction($loggedinuser, $shelfnumber, $action); C<$loggedinuser,$shelfnumber,$action> -$action can be "view" or "manage". +$action can be "view", "add", "delete", "manage", "new_public", "new_private". +Note that add/delete here refers to adding/deleting entries from the list. Deleting the list itself falls under manage. +new_public and new_private refers to creating a new public or private list. +The distinction between deleting your own entries from the list or entries from +others is made in DelFromShelf. Returns 1 if the user can do the $action in the $shelfnumber shelf. Returns 0 otherwise. @@ -455,75 +443,115 @@ Returns 0 otherwise. sub ShelfPossibleAction { my ( $user, $shelfnumber, $action ) = @_; - my $query = qq( - SELECT owner,category - FROM virtualshelves - WHERE shelfnumber=? - ); + $action= 'view' unless $action; + $user=0 unless $user; + + if($action =~ /^new/) { #no shelfnumber needed + if($action eq 'new_private') { + return $user>0; + } + elsif($action eq 'new_public') { + return $user>0 && C4::Context->preference('OpacAllowPublicListCreation'); + } + return 0; + } + + return 0 unless defined($shelfnumber); + + my $query = qq/ + SELECT IFNULL(owner,0) AS owner, category, allow_add, allow_delete_own, allow_delete_other, IFNULL(sh.borrowernumber,0) AS borrowernumber + FROM virtualshelves vs + LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber + AND sh.borrowernumber=? + WHERE vs.shelfnumber=? + /; my $sth = $dbh->prepare($query); - $sth->execute($shelfnumber); - my ( $owner, $category ) = $sth->fetchrow; - 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} || $user == 0)); # public list, superlibrarian can edit/delete - return 1 if (defined($user) and $owner eq $user ); # user owns this list. Check last. + $sth->execute($user, $shelfnumber); + my $shelf= $sth->fetchrow_hashref; + + return 0 unless $shelf && ($shelf->{category}==2 || $shelf->{owner}==$user || $shelf->{borrowernumber}==$user); + if($action eq 'view') { + #already handled in the above condition + return 1; + } + elsif($action eq 'add') { + return 0 if $user<=0; #should be logged in + return 1 if $shelf->{allow_add}==1 || $shelf->{owner}==$user; + #owner may always add + } + elsif($action eq 'delete') { + #this answer is just diplomatic: it says that you may be able to delete + #some items from that shelf + #it does not answer the question about a specific biblio + #DelFromShelf checks the situation per biblio + return 1 if $user>0 && ($shelf->{allow_delete_own}==1 || $shelf->{allow_delete_other}==1); + } + elsif($action eq 'manage') { + return 1 if $user && $shelf->{owner}==$user; + } return 0; } =head2 DelFromShelf - &DelFromShelf( $biblionumber, $shelfnumber); + $result= &DelFromShelf( $bibref, $shelfnumber, $user); -Removes bib number C<$biblionumber> from virtual virtualshelves number -C<$shelfnumber>. If the bib wasn't on that virtualshelves to begin with, -nothing happens. +Removes biblionumbers in passed arrayref from shelf C<$shelfnumber>. +If the bib wasn't on that virtualshelves to begin with, nothing happens. + +Returns 0 if no items have been deleted. =cut -#' sub DelFromShelf { - my ( $biblionumber, $shelfnumber ) = @_; - my $query = qq( - DELETE FROM virtualshelfcontents - WHERE shelfnumber=? AND biblionumber=? - ); - my $sth = $dbh->prepare($query); - $sth->execute( $shelfnumber, $biblionumber ); + my ($bibref, $shelfnumber, $user) = @_; + my $query = qq(SELECT allow_delete_own, allow_delete_other FROM virtualshelves WHERE shelfnumber=?); + my $sth= $dbh->prepare($query); + $sth->execute($shelfnumber); + my ($del_own, $del_oth)= $sth->fetchrow; + my $r; my $t=0; + + if($del_own) { + $query = qq(DELETE FROM virtualshelfcontents + WHERE shelfnumber=? AND biblionumber=? AND borrowernumber=?); + $sth= $dbh->prepare($query); + foreach my $biblionumber (@$bibref) { + $sth->execute($shelfnumber, $biblionumber, $user); + $r= $sth->rows; #Expect -1, 0 or 1 (-1 means Don't know; count as 1) + $t+= ($r==-1)? 1: $r; + } + } + if($del_oth) { + $query = qq(DELETE FROM virtualshelfcontents + WHERE shelfnumber=? AND biblionumber=? AND borrowernumber<>?); + $sth= $dbh->prepare($query); + foreach my $biblionumber (@$bibref) { + $sth->execute($shelfnumber, $biblionumber, $user); + $r= $sth->rows; + $t+= ($r==-1)? 1: $r; + } + } + return $t; } -=head2 DelShelf (old version) - - ($status, $msg) = &DelShelf($shelfnumber); - -Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must -be empty. - -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. - -=head2 DelShelf (current version) +=head2 DelShelf $Number = DelShelf($shelfnumber); This function deletes the shelf number, and all of it's content. +Authorization to do so MUST have been checked before calling, while using +ShelfPossibleAction with manage parameter. =cut sub DelShelf { - unless (@_) { - carp "DelShelf called without valid argument (shelfnumber)"; - return undef; - } - my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?"); - return $sth->execute(shift); + my ($shelfnumber)= @_; + return unless $shelfnumber && $shelfnumber =~ /^\d+$/; + my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?"); + return $sth->execute($shelfnumber); } -=head2 GetBibShelves +=head2 GetBibliosShelves This finds all the public lists that this bib record is in. @@ -536,65 +564,59 @@ sub GetBibliosShelves { SELECT vs.shelfname, vs.shelfnumber FROM virtualshelves vs JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber) - WHERE vs.category != 1 + WHERE vs.category=2 AND vc.biblionumber= ? '); $sth->execute( $biblionumber ); return $sth->fetchall_arrayref({}); } -=head2 RefreshShelvesSummary +=head2 ShelvesMax - ($total, $pubshelves, $barshelves) = RefreshShelvesSummary($sessionID, $loggedinuser, $row_count); + $howmany= ShelvesMax($context); -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. +Tells how much shelves are shown in which context. +POPUP refers to addbybiblionumber popup, MGRPAGE is managing page (in opac or +staff), COMBO refers to the Add to-combo of search results. MASTHEAD is the +main Koha toolbar with Lists button. =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); +sub ShelvesMax { + my $which= shift; + return SHELVES_POPUP_MAX if $which eq 'POPUP'; + return SHELVES_MGRPAGE_MAX if $which eq 'MGRPAGE'; + return SHELVES_COMBO_MAX if $which eq 'COMBO'; + return SHELVES_MASTHEAD_MAX if $which eq 'MASTHEAD'; + return SHELVES_MASTHEAD_MAX; } # 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 _shelf_count { + my ($owner, $category) = @_; + my @params; + # Find out how many shelves total meet the submitted criteria... + + my $query = "SELECT count(*) FROM virtualshelves vs "; + if($category==1) { + $query.= qq{ + LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber + AND sh.borrowernumber=? + WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; + @params= ($owner, $owner, $owner); + } + else { + $query.='WHERE category=2'; + @params= (); + } + my $sth = $dbh->prepare($query); + $sth->execute(@params); + my ($total)= $sth->fetchrow; + return $total; } -sub _biblionumber_sth { +sub _biblionumber_sth { #only used in obsolete sub below my ($shelf) = @_; my $query = 'select biblionumber from virtualshelfcontents where shelfnumber = ?'; my $dbh = C4::Context->dbh; @@ -605,7 +627,7 @@ sub _biblionumber_sth { $sth; } -sub each_biblionumbers (&$) { +sub each_biblionumbers (&$) { #OBSOLETE my ($code,$shelf) = @_; my $ref = _biblionumber_sth($shelf)->fetchall_arrayref; map { @@ -614,6 +636,25 @@ sub each_biblionumbers (&$) { } @$ref; } +sub _CheckShelfName { + my ($name, $cat, $owner, $number)= @_; + + my $query = qq( + SELECT DISTINCT shelfnumber + FROM virtualshelves + LEFT JOIN virtualshelfshares sh USING (shelfnumber) + WHERE shelfname=? AND shelfnumber<>?); + if($cat==1) { + $query.= ' AND (sh.borrowernumber=? OR owner=?) AND category=1'; + } + else { + $query.= ' AND category=2'; + } + my $sth = $dbh->prepare($query); + $sth->execute($cat==1? ($name, $number, $owner, $owner): ($name, $number)); + return $sth->rows>0? 0: 1; +} + 1; __END__ --- a/C4/VirtualShelves/Page.pm +++ a/C4/VirtualShelves/Page.pm @@ -22,8 +22,12 @@ package C4::VirtualShelves::Page; use strict; use warnings; + use CGI; -use C4::VirtualShelves qw/:DEFAULT RefreshShelvesSummary/; +use Exporter; +use Data::Dumper; + +use C4::VirtualShelves qw/:DEFAULT ShelvesMax/; use C4::Biblio; use C4::Items; use C4::Koha; @@ -32,11 +36,11 @@ use C4::Members; use C4::Output; use C4::Dates qw/format_date/; use C4::Tags qw(get_tags); -use Exporter; -use Data::Dumper; use C4::Csv; use C4::XSLT; +use constant VIRTUALSHELVES_COUNT => 20; + use vars qw($debug @EXPORT @ISA $VERSION); BEGIN { @@ -51,12 +55,15 @@ our %pages = ( opac => { redirect => '/cgi-bin/koha/opac-shelves.pl', }, ); -sub shelfpage ($$$$$) { +sub shelfpage { my ( $type, $query, $template, $loggedinuser, $cookie ) = @_; ( $pages{$type} ) or $type = 'opac'; $query or die "No query"; $template or die "No template"; - $template->param( loggedinuser => $loggedinuser ); + $template->param( + loggedinuser => $loggedinuser, + OpacAllowPublicListCreation => C4::Context->preference('OpacAllowPublicListCreation'), + ); my $edit; my $shelves; my @paramsloop; @@ -69,7 +76,7 @@ sub shelfpage ($$$$$) { my $marcflavour = C4::Context->preference("marcflavour"); $shelflimit = ( $type eq 'opac' ? C4::Context->preference('OPACnumSearchResults') : C4::Context->preference('numSearchResults') ); - $shelflimit = $shelflimit || 20; + $shelflimit = $shelflimit || ShelvesMax('MGRPAGE'); $shelfoffset = ( $itemoff - 1 ) * $shelflimit; # Sets the offset to begin retrieving items at $shelveslimit = $shelflimit; # Limits number of shelves returned for a given query (row_count) $shelvesoffset = ( $shelfoff - 1 ) * $shelflimit; # Sets the offset to begin retrieving shelves at (offset) @@ -84,36 +91,51 @@ sub shelfpage ($$$$$) { } my $op = $query->param('op'); - # my $imgdir = getitemtypeimagesrc(); - # my $itemtypes = GetItemTypes(); - # the format of this is unindented for ease of diff comparison to the old script # Note: do not mistake the assignment statements below for comparisons! if ( $query->param('modifyshelfcontents') ) { my ( $shelfnumber, $barcode, $item, $biblio ); if ( $shelfnumber = $query->param('viewshelf') ) { - if ( ShelfPossibleAction( $loggedinuser, $shelfnumber, 'manage' ) ) { - if ( $barcode = $query->param('addbarcode') ) { - $item = GetItem( 0, $barcode ); - if (defined $item && $item->{'itemnumber'}){ + #add to shelf + if($barcode = $query->param('addbarcode') ) { + if(ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add')) { + $item = GetItem( 0, $barcode); + if (defined $item && $item->{'itemnumber'}) { $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'} ); - AddToShelf( $biblio->{'biblionumber'}, $shelfnumber ) + AddToShelf( $biblio->{'biblionumber'}, $shelfnumber, $loggedinuser) or push @paramsloop, { duplicatebiblio => $barcode }; - } else { + } + else { push @paramsloop, { failgetitem => $barcode }; } - } else { - ( grep { /REM-(\d+)/ } $query->param ) or push @paramsloop, { nobarcode => 1 }; - foreach ( $query->param ) { + } + else { + push @paramsloop, { nopermission => $shelfnumber }; + } + } + elsif(grep { /REM-(\d+)/ } $query->param) { + #remove item(s) from shelf + if(ShelfPossibleAction($loggedinuser, $shelfnumber, 'delete')) { + #This is just a general okay; DelFromShelf checks further + my @bib; + foreach($query->param) { /REM-(\d+)/ or next; - $debug and warn "SHELVES: user $loggedinuser removing item $1 from shelf $shelfnumber"; - DelFromShelf( $1, $shelfnumber ); # $1 is biblionumber + push @bib, $1; #$1 is biblionumber + } + my $t= DelFromShelf(\@bib, $shelfnumber, $loggedinuser); + if($t==0) { + push @paramsloop, {nothingdeleted => $shelfnumber}; + } + elsif($t<@bib) { + push @paramsloop, {somedeleted => $shelfnumber}; } } - } else { - push @paramsloop, { nopermission => $shelfnumber }; + else { + push @paramsloop, { nopermission => $shelfnumber }; + } } - } else { + } + else { push @paramsloop, { noshelfnumber => 1 }; } } @@ -148,24 +170,31 @@ sub shelfpage ($$$$$) { SWITCH: { if ($op) { - unless ($okmanage) { - push @paramsloop, { nopermission => $shelfnumber }; - last SWITCH; - } + #Saving modified shelf if ( $op eq 'modifsave' ) { + unless ($okmanage) { + push @paramsloop, { nopermission => $shelfnumber }; + last SWITCH; + } my $shelf = { 'shelfname' => $query->param('shelfname'), - 'category' => $query->param('category'), 'sortfield' => $query->param('sortfield'), }; - - ModShelf( $shelfnumber, $shelf ); - - } elsif ( $op eq 'modif' ) { + if($query->param('category')) { #optional + $shelf->{category}= $query->param('category'); + } + unless(ModShelf($shelfnumber, $shelf )) { + push @paramsloop, {modifyfailure => $shelf->{shelfname}}; + last SWITCH; + } + } + #Editing a shelf + elsif ( $op eq 'modif' ) { my ( $shelfnumber2, $shelfname, $owner, $category, $sortfield ) = GetShelf($shelfnumber); my $member = GetMember( 'borrowernumber' => $owner ); my $ownername = defined($member) ? $member->{firstname} . " " . $member->{surname} : ''; $edit = 1; + $sortfield='' unless $sortfield; $template->param( edit => 1, shelfnumber => $shelfnumber2, @@ -179,6 +208,8 @@ sub shelfpage ($$$$$) { } last SWITCH; } + + #View a shelf if ( $shelfnumber = $query->param('viewshelf') ) { # explicitly fetch this shelf my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber); @@ -247,21 +278,31 @@ sub shelfpage ($$$$$) { authorsort => $authorsort, yearsort => $yearsort, manageshelf => $manageshelf, + allowremovingitems => ShelfPossibleAction( $loggedinuser, $shelfnumber, 'delete'), + allowaddingitem => ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add'), "category$category" => 1, category => $category, itemsloop => $items, + showprivateshelves => $category==1, ); } else { push @paramsloop, { nopermission => $shelfnumber }; } last SWITCH; } + if ( $query->param('shelves') ) { my $stay = 1; + + #Add a shelf if ( my $newshelf = $query->param('addshelf') ) { # note: a user can always add a new shelf - my $shelfnumber = AddShelf( $newshelf, $query->param('owner'), $query->param('category'), $query->param('sortfield') ); + my $shelfnumber = AddShelf( { + shelfname => $newshelf, + sortfield => $query->param('sortfield'), + category => $query->param('category') }, + $query->param('owner') ); $stay = 1; if ( $shelfnumber == -1 ) { #shelf already exists. $showadd = 1; @@ -272,6 +313,8 @@ sub shelfpage ($$$$$) { exit; } } + + #Deleting a shelf (asking for confirmation if it has entries) foreach ( $query->param() ) { /DEL-(\d+)/ or next; $delflag = 1; @@ -313,7 +356,6 @@ sub shelfpage ($$$$$) { } push( @paramsloop, { delete_ok => $name } ); - # print $query->redirect($pages{$type}->{redirect}); exit; $stay = 0; } $showadd = 1; @@ -323,7 +365,7 @@ sub shelfpage ($$$$$) { } last SWITCH; } - } + } # end of SWITCH block (@paramsloop) and $template->param( paramsloop => \@paramsloop ); $showadd and $template->param( showadd => 1 ); @@ -337,7 +379,7 @@ sub shelfpage ($$$$$) { my %line; $shelflist->{$element}->{shelf} = $element; my $category = $shelflist->{$element}->{'category'}; - my $owner = $shelflist->{$element}->{'owner'}; + my $owner = $shelflist->{$element}->{'owner'}||0; my $canmanage = ShelfPossibleAction( $loggedinuser, $element, 'manage' ); my $sortfield = $shelflist->{$element}->{'sortfield'}; if ( $sortfield ){ @@ -349,7 +391,7 @@ sub shelfpage ($$$$$) { } $shelflist->{$element}->{"viewcategory$category"} = 1; $shelflist->{$element}->{manageshelf} = $canmanage; - if ( $owner eq $loggedinuser or $canmanage ) { + if($canmanage || ($loggedinuser && $owner==$loggedinuser)) { $shelflist->{$element}->{'mine'} = 1; } my $member = GetMember( 'borrowernumber' => $owner ); @@ -393,28 +435,15 @@ sub shelfpage ($$$$$) { $template->param( seflag => 1 ); } - #FIXME: This refresh really only needs to happen when there is a modification of some sort - # to the shelves, but the above code is so convoluted in its handling of the various - # options, it is easier to do this refresh every time C4::VirtualShelves::Page.pm is - # called - - my ( $total, $pubshelves, $barshelves ) = RefreshShelvesSummary( $query->cookie("CGISESSID"), $loggedinuser, ( $loggedinuser == -1 ? 20 : 10 ) ); - - if ( defined $barshelves ) { - $template->param( - barshelves => scalar( @{ $barshelves } ), +#Next call updates the shelves for the Lists button. +#May not always be needed (when nothing changed), but doesn't take much. + my ($total, $pubshelves, $barshelves) = C4::VirtualShelves::GetSomeShelfNames($loggedinuser, 'MASTHEAD'); + $template->param( + barshelves => $total->{bartotal}, barshelvesloop => $barshelves, - ); - $template->param( bartotal => $total->{'bartotal'}, ) if ( $total->{'bartotal'} > scalar( @{ $barshelves } ) ); - } - - if ( defined $pubshelves ) { - $template->param( - pubshelves => scalar( @{ $pubshelves } ), + pubshelves => $total->{pubtotal}, pubshelvesloop => $pubshelves, - ); - $template->param( pubtotal => $total->{'pubtotal'}, ) if ( $total->{'pubtotal'} > scalar( @{ $pubshelves } ) ); - } + ); output_html_with_http_headers $query, $cookie, $template->output; } --- a/catalogue/search.pl +++ a/catalogue/search.pl @@ -147,7 +147,7 @@ use C4::Search; use C4::Languages qw(getAllLanguages); use C4::Koha; use C4::Members qw(GetMember); -use C4::VirtualShelves qw(GetRecentShelves); +use C4::VirtualShelves; use POSIX qw(ceil floor); use C4::Branch; # GetBranches @@ -695,21 +695,13 @@ if ($query_desc || $limit_desc) { # VI. BUILD THE TEMPLATE # Build drop-down list for 'Add To:' menu... - -my $row_count = 10; # FIXME:This probably should be a syspref -my ($pubshelves, $total) = GetRecentShelves(2, $row_count, undef); -my ($barshelves, $total) = GetRecentShelves(1, $row_count, $borrowernumber); - -if (@{$pubshelves}) { - $template->param( addpubshelves => scalar @{$pubshelves}); - $template->param( addpubshelvesloop => $pubshelves); -} - -if (@{$barshelves}) { - $template->param( addbarshelves => scalar @{$barshelves}); - $template->param( addbarshelvesloop => $barshelves); -} - - +my ($totalref, $pubshelves, $barshelves)= + C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1); +$template->param( + addbarshelves => $totalref->{bartotal}, + addbarshelvesloop => $barshelves, + addpubshelves => $totalref->{pubtotal}, + addpubshelvesloop => $pubshelves, + ); output_html_with_http_headers $cgi, $cookie, $template->output; --- a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/addbybiblionumber.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/addbybiblionumber.tt @@ -7,6 +7,13 @@ +[% UNLESS (authorized) %] +

+ [% IF (errcode==1) %]Could not make new shelf. Please check the name.
[% END %] + [% IF (errcode==2) %]Sorry, you do not have permission to add items to this list.
[% END %] + Close this window. +

+[% ELSE %]
[% IF ( multiple ) %] @@ -29,11 +36,29 @@ [% UNLESS ( shelfnumber ) %] -[% IF ( CGIvirtualshelves ) %] [% UNLESS ( newshelf ) %] +[% UNLESS ( newshelf ) %]
Select an existing list
    -
  1. [% CGIvirtualshelves %]
  2. +
  3. + + +
[% FOREACH biblio IN biblios %][% END %] [% UNLESS ( biblionumbers ) %] @@ -43,9 +68,8 @@ [% END %]
-

... or...

[% END %] - - [% END %] +

... or...

+[% END %]
Add to a new list:
  1. @@ -66,7 +90,6 @@
@@ -85,3 +108,4 @@
[% INCLUDE 'intranet-bottom.inc' %] +[% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt @@ -24,7 +24,7 @@ $(document).ready(function(){ function confirmDelete(message){ if (window.confirm(message)) { - location.href="/cgi-bin/koha/virtualshelves/shelves.pl?[% IF ( showprivateshelves ) %] display=privateshelves&[% END %]shelves=1&DEL-[% shelfnumber %]=1&shelfoff=[% shelfoff %]"; + location.href="/cgi-bin/koha/virtualshelves/shelves.pl?[% IF ( showprivateshelves ) %]display=privateshelves&[% END %]shelves=1&DEL-[% shelfnumber %]=1&shelfoff=[% shelfoff %]"; } else { return false; } @@ -162,7 +162,7 @@ function placeHold () {
Contents of [% shelfname | html %] - [% IF ( manageshelf ) %] + [% IF ( itemsloop ) %]

|

[% END %] @@ -170,7 +170,7 @@ function placeHold () {
[% pagination_bar %]
- [% IF ( manageshelf ) %][% END %] + [% IF ( itemsloop ) %][% END %] [% UNLESS ( item_level_itypes ) %][% END %] @@ -183,7 +183,7 @@ function placeHold () { [% ELSE %] [% END %] - [% IF ( manageshelf ) %] + [% IF ( itemsloop ) %] [% END %]
  Item TypeTitle Author
[% IF ( itemsloo.confirm ) %] @@ -210,9 +210,9 @@ function placeHold () {
- [% IF ( manageshelf ) %] + [% IF ( itemsloop ) %] - + [% IF ( allowremovingitems ) %][% END %] [% END %]
@@ -223,7 +223,7 @@ function placeHold () {
[% END %] -[% IF ( manageshelf ) %] +[% IF ( allowaddingitem ) %]
@@ -240,7 +240,7 @@ function placeHold () {
-[% END %] +[% END %] [% IF ( debug ) %] [% IF ( edit ) %]
Edit is on ([% shelfname | html %])
[% END %] @@ -269,7 +269,6 @@ function placeHold () { [% END %] @@ -299,11 +298,6 @@ function placeHold () { [% ELSE %] [% END %] - [% IF ( category3 ) %] - - [% ELSE %] - - [% END %] [% END %] @@ -317,8 +311,8 @@ function placeHold () {
+ + [% END %] @@ -354,7 +348,6 @@ function placeHold () { [% IF ( shelveslooppri.authorsort ) %]Author[% ELSIF ( shelveslooppri.yearsort ) %]Year[% ELSE %]Title[% END %] [% IF ( shelveslooppri.viewcategory1 ) %]Private[% END %] [% IF ( shelveslooppri.viewcategory2 ) %]Public[% END %] - [% IF ( shelveslooppri.viewcategory3 ) %]Open[% END %] [% IF ( shelveslooppri.mine ) %] @@ -408,7 +401,6 @@ function placeHold () { [% IF ( shelvesloo.authorsort ) %]Author[% ELSIF ( shelvesloo.yearsort ) %]Year[% ELSE %]Title[% END %] [% IF ( shelvesloo.viewcategory1 ) %]Private[% END %] [% IF ( shelvesloo.viewcategory2 ) %]Public[% END %] - [% IF ( shelvesloo.viewcategory3 ) %]Open[% END %] [% IF ( shelvesloo.manageshelf ) %] --- a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc +++ a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc @@ -138,37 +138,29 @@ [% FOREACH pubshelvesloo IN pubshelvesloop %]
  • [% pubshelvesloo.shelfname |html %]
  • [% END %] +
  • [View All]
  • [% ELSE %] No Public Lists [% END %] - [% IF ( pubtotal ) %] - - [% END %] [% IF ( opacuserlogin ) %] - [% IF ( loggedinusername ) %] -

    Your Lists

    +

    Your Lists

    + [% IF ( loggedinusername ) %] [% IF ( barshelves ) %] [% ELSE %] - No Private Lists - [% END %] - [% IF ( bartotal ) %] - + [% END %] - - [% ELSE %] - [% END %] + [% ELSE %] + + [% END %] [% END %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-addbybiblionumber.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-addbybiblionumber.tt @@ -64,7 +64,9 @@
  • [% FOREACH biblio IN biblios %] [% END %]
    Cancel
    @@ -72,8 +74,11 @@ [% END %] [% ELSE %]

    - This is not an open list. - Items cannot be added to it. + [% IF (errcode==1) %] + Could not create new list. Please check if the name is unique. + [% ELSE %] + Sorry, you cannot add items to this list. + [% END %]

    [% END %]

    --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt @@ -175,6 +175,15 @@ $(function() { [% IF ( paramsloo.unrecognized ) %]

    ERROR: List number [% paramsloo.unrecognized %] unrecognized.
    [% END %] + [% IF ( paramsloo.modifyfailure) %] +
    ERROR: Shelf could not be renamed to [% paramsloo.modifyfailure %]. This name may not be unique for this type of list. Please check.
    + [% END %] + [% IF ( paramsloo.nothingdeleted) %] +
    Warning: You could not delete any selected items from this shelf.
    + [% END %] + [% IF ( paramsloo.somedeleted) %] +
    Warning: You could not delete all selected items from this shelf.
    + [% END %] [% END %] @@ -351,21 +360,20 @@ $(function() { [% END %] - [% IF ( manageshelf ) %] - - [% IF ( itemsloop ) %] + [% IF ( itemsloop && allowremovingitems ) %] +
    - [% ELSE %] +
    + [% ELSIF ( !itemsloop && manageshelf ) %]
    - [% END %] - [% END %]
    + [% END %] [% IF ( edit ) %] @@ -386,11 +394,13 @@ $(function() {
  • + [% IF (OpacAllowPublicListCreation) %] + [% END %]
  • @@ -444,7 +454,6 @@ $(function() { [% IF ( shelveslooppri.viewcategory1 ) %]Private[% END %] [% IF ( shelveslooppri.viewcategory2 ) %]Public[% END %] - [% IF ( shelveslooppri.viewcategory3 ) %]Open[% END %] [% IF ( shelveslooppri.mine ) %] @@ -511,7 +520,6 @@ $(function() { [% IF ( shelvesloo.viewcategory1 ) %]Private[% END %] [% IF ( shelvesloo.viewcategory2 ) %]Public[% END %] - [% IF ( shelvesloo.viewcategory3 ) %]Open[% END %] [% IF ( shelvesloo.mine ) %] @@ -574,7 +582,9 @@ $(function() { --- a/opac/opac-addbybiblionumber.pl +++ a/opac/opac-addbybiblionumber.pl @@ -25,26 +25,11 @@ use strict; use warnings; -use C4::Biblio; use CGI; -use C4::VirtualShelves qw/:DEFAULT GetAllShelves RefreshShelvesSummary/; -use C4::Auth; +use C4::Biblio; +use C4::VirtualShelves qw/:DEFAULT GetAllShelves/; use C4::Output; -use C4::Auth qw/get_session/; -use C4::Debug; - -#splits incoming biblionumber(s) to array and adds each to shelf. -sub AddBibliosToShelf { - my ($shelfnumber,@biblionumber)=@_; - - # multiple bibs might come in as '/' delimited string (from where, i don't see), or as array. - if (scalar(@biblionumber) == 1) { - @biblionumber = (split /\//,$biblionumber[0]); - } - for my $bib (@biblionumber){ - AddToShelf($bib, $shelfnumber); - } -} +use C4::Auth; my $query = new CGI; my @biblionumber = $query->param('biblionumber'); @@ -53,6 +38,9 @@ my $newshelf = $query->param('newshelf'); my $shelfnumber = $query->param('shelfnumber'); my $newvirtualshelf = $query->param('newvirtualshelf'); my $category = $query->param('category'); +my $authorized = 1; +my $errcode = 0; +my @biblios; my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { @@ -63,72 +51,120 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); -if ($newvirtualshelf) { - $shelfnumber = AddShelf( $newvirtualshelf, $loggedinuser, $category ); - AddBibliosToShelf($shelfnumber, @biblionumber); - RefreshShelvesSummary($query->cookie("CGISESSID"),$loggedinuser,($loggedinuser == -1 ? 20 : 10)); - print $query->header; - print ""; - exit; +if( $newvirtualshelf) { + HandleNewVirtualShelf(); + exit if $authorized; + ShowTemplate(); #error message } +elsif($shelfnumber) { + HandleShelfNumber(); + exit if $authorized; + ShowTemplate(); #error message +} +elsif($selectedshelf) { + HandleSelectedShelf(); + LoadBib() if $authorized; + ShowTemplate(); +} +else { + HandleSelect(); + LoadBib() if $authorized; + ShowTemplate(); +} +#end -# verify user is authorized to perform the action on the shelf... -my $authorized = 1; -if ($selectedshelf) { - $authorized = 0 unless ShelfPossibleAction( $loggedinuser, $selectedshelf ); +sub AddBibliosToShelf { + #splits incoming biblionumber(s) to array and adds each to shelf. + my ($shelfnumber,@biblionumber)=@_; + + #multiple bibs might come in as '/' delimited string (from where, i don't see), or as array. + if (scalar(@biblionumber) == 1) { + @biblionumber = (split /\//,$biblionumber[0]); + } + for my $bib (@biblionumber) { + AddToShelf($bib, $shelfnumber, $loggedinuser); + } } -if ($shelfnumber && ($shelfnumber != -1)) { - AddBibliosToShelf($shelfnumber,@biblionumber); - RefreshShelvesSummary($query->cookie("CGISESSID"),$loggedinuser,($loggedinuser == -1 ? 20 : 10)); +sub HandleNewVirtualShelf { + if($authorized= ShelfPossibleAction($loggedinuser, undef, $category==1? 'new_private': 'new_public')) { + $shelfnumber = AddShelf( { + shelfname => $newvirtualshelf, + category => $category }, $loggedinuser); + if($shelfnumber == -1) { + $authorized=0; + $errcode=1; + return; + } + AddBibliosToShelf($shelfnumber, @biblionumber); + #Reload the page where you came from print $query->header; - print ""; - exit; + print ""; + } } -else { - if($selectedshelf){ - # adding to specific shelf - my ( $singleshelf, $singleshelfname, $singlecategory ) = GetShelf( $query->param('selectedshelf') ); - $template->param( - singleshelf => 1, - shelfnumber => $singleshelf, - shelfname => $singleshelfname, - "category$singlecategory" => 1 - ); - } else { - my $privateshelves = GetAllShelves(1,$loggedinuser); - if(@{$privateshelves}){ - $template->param ( - privatevirtualshelves => $privateshelves, - existingshelves => 1 - ); - } - my $publicshelves = GetAllShelves(2,$loggedinuser); - if(@{$publicshelves}){ - $template->param ( - publicvirtualshelves => $publicshelves, - existingshelves => 1 - ); - } +sub HandleShelfNumber { + if($authorized= ShelfPossibleAction($loggedinuser, $shelfnumber, 'add')) { + AddBibliosToShelf($shelfnumber,@biblionumber); + #Close this page and return + print $query->header; + print ""; + } +} +sub HandleSelectedShelf { + if($authorized= ShelfPossibleAction( $loggedinuser, $selectedshelf, 'add')){ + #adding to specific shelf + my ($singleshelf, $singleshelfname, $singlecategory)= GetShelf($query->param('selectedshelf')); + $template->param( + singleshelf => 1, + shelfnumber => $singleshelf, + shelfname => $singleshelfname, + "category$singlecategory" => 1 + ); + } } - my @biblios; - for my $bib (@biblionumber) { - my $data = GetBiblioData( $bib ); - push(@biblios, - { biblionumber => $bib, - title => $data->{'title'}, - author => $data->{'author'}, - } ); - } - $template->param ( - newshelf => $newshelf, - multiple => (scalar(@biblios) > 1), - total => scalar @biblios, - biblios => \@biblios, - authorized => $authorized, + +sub HandleSelect { + return unless $authorized= $loggedinuser>0; + my $privateshelves = GetAllShelves(1,$loggedinuser,1); + if(@{$privateshelves}){ + $template->param ( + privatevirtualshelves => $privateshelves, + existingshelves => 1 + ); + } + my $publicshelves = GetAllShelves(2,$loggedinuser,1); + if(@{$publicshelves}){ + $template->param ( + publicvirtualshelves => $publicshelves, + existingshelves => 1 ); + } +} + +sub LoadBib { + for my $bib (@biblionumber) { + my $data = GetBiblioData( $bib ); + push(@biblios, + { biblionumber => $bib, + title => $data->{'title'}, + author => $data->{'author'}, + } ); + } + $template->param( + multiple => (scalar(@biblios) > 1), + total => scalar @biblios, + biblios => \@biblios, + ); +} - output_html_with_http_headers $query, $cookie, $template->output; +sub ShowTemplate { + $template->param ( + newshelf => $newshelf||0, + authorized => $authorized, + errcode => $errcode, + OpacAllowPublicListCreation => C4::Context->preference('OpacAllowPublicListCreation'), + ); + output_html_with_http_headers $query, $cookie, $template->output; } --- a/opac/opac-search.pl +++ a/opac/opac-search.pl @@ -41,6 +41,7 @@ use URI::Escape; use Storable qw(thaw freeze); + my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold"); # create a new CGI object # FIXME: no_undef_params needs to be tested @@ -718,24 +719,14 @@ if ($query_desc || $limit_desc) { # VI. BUILD THE TEMPLATE # Build drop-down list for 'Add To:' menu... -my $session = get_session($cgi->cookie("CGISESSID")); -my @addpubshelves; -my $pubshelves = $session->param('pubshelves'); -my $barshelves = $session->param('barshelves'); -foreach my $shelf (@$pubshelves) { - next if ( ($shelf->{'owner'} != ($borrowernumber ? $borrowernumber : -1)) && ($shelf->{'category'} < 3) ); - push (@addpubshelves, $shelf); -} - -if (@addpubshelves) { - $template->param( addpubshelves => scalar (@addpubshelves)); - $template->param( addpubshelvesloop => \@addpubshelves); -} - -if (defined $barshelves) { - $template->param( addbarshelves => scalar (@$barshelves)); - $template->param( addbarshelvesloop => $barshelves); -} +my ($totalref, $pubshelves, $barshelves)= + C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1); +$template->param( + addbarshelves => $totalref->{bartotal}, + addbarshelvesloop => $barshelves, + addpubshelves => $totalref->{pubtotal}, + addpubshelvesloop => $pubshelves, + ); my $content_type = ($format eq 'rss' or $format eq 'atom') ? $format : 'html'; --- a/opac/opac-shelves.pl +++ a/opac/opac-shelves.pl @@ -32,9 +32,5 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user({ authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ), }); $template->param(listsview => 1); -# if $loggedinuser is not defined, set it to -1, which should -# not correspond to any real borrowernumber. -# FIXME: this is a hack to temporarily avoid changing several -# routines in C4::VirtualShelves and C4::VirtualShelves::page -# to deal with lists accessed during an anonymous OPAC session -shelfpage('opac', $query, $template, (defined($loggedinuser) ? $loggedinuser : -1), $cookie); + +shelfpage('opac', $query, $template, $loggedinuser, $cookie); --- a/virtualshelves/addbybiblionumber.pl +++ a/virtualshelves/addbybiblionumber.pl @@ -59,44 +59,25 @@ =cut use strict; -#use warnings; FIXME - Bug 2505 -use C4::Biblio; +use warnings; + use CGI; +use C4::Biblio; use C4::Output; -use C4::VirtualShelves qw/:DEFAULT GetRecentShelves/; -use C4::Circulation; +use C4::VirtualShelves qw/:DEFAULT GetAllShelves/; use C4::Auth; -# splits incoming biblionumber(s) to array and adds each to shelf. -sub AddBibliosToShelf { - my ($shelfnumber,@biblionumber)=@_; - - # multiple bibs might come in as '/' delimited string (from where, i don't see), or as array. - # (Note : they come in as '/' when added from the cart) - if (scalar(@biblionumber) == 1) { - @biblionumber = (split /\//,$biblionumber[0]); - } - for my $bib (@biblionumber){ - AddToShelf($bib, $shelfnumber); - } -} my $query = new CGI; - -# If set, then single item case. -my $biblionumber = $query->param('biblionumber'); - -# If set, then multiple item case. -my @biblionumber = $query->param('biblionumber'); -my $biblionumbers = $query->param('biblionumbers'); - +my @biblionumber = HandleBiblioPars(); my $shelfnumber = $query->param('shelfnumber'); my $newvirtualshelf = $query->param('newvirtualshelf'); my $newshelf = $query->param('newshelf'); my $category = $query->param('category'); my $sortfield = $query->param('sortfield'); my $confirmed = $query->param('confirmed') || 0; - +my $authorized = 1; +my $errcode = 0; my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { @@ -108,120 +89,122 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); -my @biblionumbers; -if ($biblionumbers) { - @biblionumbers = split '/', $biblionumbers; -} else { - @biblionumbers = (@biblionumber); +if( $newvirtualshelf) { + HandleNewVirtualShelf(); + exit if $authorized; + ShowTemplate(); #error message +} +elsif($shelfnumber && $confirmed) { + HandleShelfNumber(); + exit if $authorized; + ShowTemplate(); #error message +} +elsif($shelfnumber) { #still needs confirmation + HandleSelectedShelf(); + LoadBib() if $authorized; + ShowTemplate(); } -if (scalar(@biblionumber) == 1) { - @biblionumber = (split /\//,$biblionumber[0]); +else { + HandleSelect(); + LoadBib(); + ShowTemplate(); } +#end -$shelfnumber = AddShelf( $newvirtualshelf, $loggedinuser, $category, $sortfield ) if $newvirtualshelf; -if ( $shelfnumber || ( $shelfnumber == -1 ) ) { # the shelf already exist. - - if ($confirmed == 1) { - AddBibliosToShelf($shelfnumber,@biblionumber); - print - "Content-Type: text/html\n\n"; - exit; - } else { - my ( $singleshelf, $singleshelfname, $singlecategory ) = GetShelf( $query->param('shelfnumber') ); - my @biblios; - for my $bib (@biblionumber) { - my $data = GetBiblioData( $bib ); - push(@biblios, - { biblionumber => $bib, - title => $data->{'title'}, - author => $data->{'author'}, - } ); - } - - $template->param - ( - biblionumber => \@biblionumber, - biblios => \@biblios, - multiple => (scalar(@biblionumber) > 1), - singleshelf => 1, - shelfname => $singleshelfname, - shelfnumber => $singleshelf, - total => scalar(@biblionumber), - confirm => 1, - ); +sub HandleBiblioPars { + my @bib= $query->param('biblionumber'); + if(@bib==0 && $query->param('biblionumbers')) { + my $str= $query->param('biblionumbers'); + @bib= split '/', $str; + } + elsif(@bib==1 && $bib[0]=~/\//) { + @bib= split '/', $bib[0]; + } + return @bib; +} + +sub AddBibliosToShelf { + my ($shelfnumber, @biblionumber)=@_; + for my $bib (@biblionumber){ + AddToShelf($bib, $shelfnumber, $loggedinuser); + } +} + +sub HandleNewVirtualShelf { + $shelfnumber = AddShelf( { + shelfname => $newvirtualshelf, + sortfield => $sortfield, + category => $category }, $loggedinuser); + if($shelfnumber == -1) { + $authorized=0; + $errcode=1; #add failed + return; } + AddBibliosToShelf($shelfnumber, @biblionumber); + #Reload the page where you came from + print $query->header; + print ""; } -else { # this shelf doesn't already exist. -# my $limit = 10; - my ($shelflist); - my @shelvesloop; - my %shelvesloop; - - #grab each type of shelf, open (type 3) should not be limited by user. - foreach my $shelftype (1,2,3) { - my ($shelflist) = GetRecentShelves($shelftype, undef, $shelftype == 3 ? undef : $loggedinuser); - for my $shelf (@{ $shelflist }) { - push(@shelvesloop, $shelf->{shelfnumber}); - $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname}; - } + +sub HandleShelfNumber { + if($authorized= ShelfPossibleAction($loggedinuser, $shelfnumber, 'add')) { + AddBibliosToShelf($shelfnumber, @biblionumber); + #Close this page and return + print $query->header; + print ""; + } + else { + $errcode=2; #no perm } +} - if( @shelvesloop ){ - my $CGIvirtualshelves = CGI::scrolling_list - ( - -name => 'shelfnumber', - -values => \@shelvesloop, - -labels => \%shelvesloop, - -size => 1, - -tabindex => '', - -multiple => 0 - ); - $template->param - ( - CGIvirtualshelves => $CGIvirtualshelves, - ); +sub HandleSelectedShelf { + if($authorized= ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add')){ + #confirm adding to specific shelf + my ($singleshelf, $singleshelfname, $singlecategory)= GetShelf($shelfnumber); + $template->param( + singleshelf => 1, + shelfnumber => $singleshelf, + shelfname => $singleshelfname, + "category$singlecategory" => 1 + ); } - my @biblios; - for my $bib (@biblionumber) { - my $data = GetBiblioData( $bib ); - push(@biblios, - { biblionumber => $bib, - title => $data->{'title'}, - author => $data->{'author'}, - } ); - } + else { + $errcode=2; #no perm + } +} + +sub HandleSelect { + my $privateshelves = GetAllShelves(1,$loggedinuser,1); + my $publicshelves = GetAllShelves(2,$loggedinuser,1); $template->param( - newshelf => $newshelf, - biblios=>\@biblios, - multiple => (scalar(@biblionumber) > 1), - total => scalar(@biblionumber), + privatevirtualshelves => $privateshelves, + publicvirtualshelves => $publicshelves, ); +} - unless (@biblionumbers) { - my ( $bibliocount, @biblios ) = GetBiblio($biblionumber); - - $template->param - ( - biblionumber => $biblionumber, - title => $biblios[0]->{'title'}, - author => $biblios[0]->{'author'}, - ); - } else { - my @biblioloop = (); - foreach my $biblionumber (@biblionumbers) { - my ( $bibliocount, @biblios ) = GetBiblio($biblionumber); - my %biblioiter = ( - title=>$biblios[0]->{'title'}, - author=>$biblios[0]->{'author'} - ); - push @biblioloop, \%biblioiter; - } - $template->param - ( - biblioloop => \@biblioloop, - biblionumbers => $biblionumbers - ); +sub LoadBib { + my @biblios; + for my $bib (@biblionumber) { + my $data = GetBiblioData($bib); + push(@biblios, + { biblionumber => $bib, + title => $data->{'title'}, + author => $data->{'author'}, + } ); } - + $template->param( + multiple => (scalar(@biblios) > 1), + total => scalar @biblios, + biblios => \@biblios, + ); +} + +sub ShowTemplate { + $template->param ( + newshelf => $newshelf||0, + authorized => $authorized, + errcode => $errcode, + ); + output_html_with_http_headers $query, $cookie, $template->output; } -output_html_with_http_headers $query, $cookie, $template->output; --