# 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;
+require C4::Auth;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
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
+ &RefreshShelvesSummary &SetShelvesLimit
+ );
}
+
my $dbh = C4::Context->dbh;
=head1 NAME
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
+=head2 GetShelves
-=item 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:
-
-C<mincategory> : 2 if the list is for "Public", 3 for "Open".
-virtualshelves of the owner are always selected, whatever the category
+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:
-=over 4
+=over
=item C<$shelfhash-E<gt>{shelfname}>
=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,
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:
# 2|6|Josh Ferraro|51|en_fuego|106
}
-=item GetShelf
+=head2 GetRecentShelves
+
+ ($shelflist) = GetRecentShelves(1, $limit, $owner)
+
+This function returns a references 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 (@shelflist);
+ my $total = _shelf_count($owner, $mincategory);
+ my @params = ($owner, $mincategory, 0, $row_count); #FIXME: offset is hardcoded here, but could be passed in for enhancements
+ shift @params if (not defined $owner);
+ my $query = "SELECT * FROM virtualshelves";
+ $query .= ((defined $owner) ? " WHERE owner = ? AND category = ?" : " WHERE category >= ? ");
+ $query .= " ORDER BY lastmodified DESC LIMIT ?, ?";
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@params);
+ @shelflist = $sth->fetchall_arrayref({});
+ return ( \@shelflist, $total );
+}
+
+=head2 GetShelf
(shelfnumber,shelfname,owner,category,sortfield) = &GetShelf($shelfnumber);
=cut
-sub GetShelf {
+sub GetShelf ($) {
my ($shelfnumber) = @_;
my $query = qq(
SELECT shelfnumber, shelfname, owner, category, sortfield
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
=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,
- biblio.*, biblioitems.itemtype, itemtypes.*
+ " SELECT vc.biblionumber, vc.shelfnumber, vc.dateadded, itemtypes.*,
+ biblio.*, biblioitems.itemtype, biblioitems.publicationyear, 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() ... ]
# or newer, for your version of DBI.
}
-=item AddShelf
+=head2 AddShelf
$shelfnumber = &AddShelf( $shelfname, $owner, $category);
=cut
sub AddShelf {
- my ( $shelfname, $owner, $category ) = @_;
+ my ( $shelfname, $owner, $category, $sortfield ) = @_;
my $query = qq(
SELECT *
FROM virtualshelves
( $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
);
$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)
$sth->execute( @bind_params );
}
-=item ShelfPossibleAction
+=head2 ShelfPossibleAction
ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
my $sth = $dbh->prepare($query);
$sth->execute($shelfnumber);
my ( $owner, $category ) = $sth->fetchrow;
- return 1 if ( $category >= 3); # open list
+ my $borrower = 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.
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
$sth->execute( $shelfnumber, $biblionumber );
}
-=item DelShelf (old version)
+=head2 DelShelf (old version)
($status, $msg) = &DelShelf($shelfnumber);
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);
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 ($$$) {
+
+ 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->[0]);
+ $session->param('pubshelves', $pubshelves->[0]);
+ $session->param('totshelves', $total);
+
+ # likewise the userenv...
+ C4::Context->set_shelves_userenv('bar',$barshelves->[0]);
+ C4::Context->set_shelves_userenv('pub',$pubshelves->[0]);
+ 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 <info@koha.org>
+Koha Development Team <http://koha-community.org/>
=head1 SEE ALSO