opac.css - button background fix for input.icon
[koha.git] / C4 / VirtualShelves.pm
1 # -*- tab-width: 8 -*-
2 # Please use 8-character tabs for this file (indents are every 4 characters)
3
4 package C4::VirtualShelves;
5
6
7 # Copyright 2000-2002 Katipo Communications
8 #
9 # This file is part of Koha.
10 #
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
14 # version.
15 #
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along with
21 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
22 # Suite 330, Boston, MA  02111-1307 USA
23
24 use strict;
25 use Carp;
26 use C4::Context;
27 use C4::Circulation;
28 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
29
30 BEGIN {
31         # set the version for version checking
32         $VERSION = 3.02;
33         require Exporter;
34         @ISA    = qw(Exporter);
35         @EXPORT = qw(
36         &GetShelves &GetShelfContents &GetShelf
37
38         &AddToShelf &AddToShelfFromBiblio &AddShelf
39
40         &ModShelf
41         &ShelfPossibleAction
42         &DelFromShelf &DelShelf
43         );
44         @EXPORT_OK = qw(&GetShelvesSummary);
45 }
46
47 my $dbh = C4::Context->dbh;
48
49 =head1 NAME
50
51 C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves
52
53 =head1 SYNOPSIS
54
55   use C4::VirtualShelves;
56
57 =head1 DESCRIPTION
58
59 This module provides functions for manipulating virtual virtualshelves,
60 including creating and deleting virtualshelves, and adding and removing
61 items to and from virtualshelves.
62
63 =head1 FUNCTIONS
64
65 =over 2
66
67 =item GetShelves
68
69   $shelflist = &GetShelves($owner);
70   $shelflist = &GetShelves($owner, $mincategory);
71   $shelflist = &GetShelves($owner, $mincategory, $limit);
72   ($shelfnumber, $shelfhash) = each %{$shelflist};
73
74 Looks up the virtual virtualshelves, and returns a summary. C<$shelflist>
75 is a reference-to-hash. The keys are the virtualshelves numbers
76 (C<$shelfnumber>, above), and the values (C<$shelfhash>, above) are
77 themselves references-to-hash, with the following keys:
78
79 C<mincategory> : 2 if the list is for "Public", 3 for "Open".
80 virtualshelves of the owner are always selected, whatever the category
81
82 =over 4
83
84 =item C<$shelfhash-E<gt>{shelfname}>
85
86 A string. The name of the shelf.
87
88 =item C<$shelfhash-E<gt>{count}>
89
90 The number of virtuals on that virtualshelves.
91
92 =back
93
94 =cut
95
96 sub GetShelves {
97     my ($owner, $mincategory, $limit) = @_;
98         ($mincategory and $mincategory =~ /^\d+$/) or $mincategory = 2;
99         (      $limit and       $limit =~ /^\d+$/) or $limit = undef;
100     my $query = qq(
101         SELECT virtualshelves.shelfnumber, virtualshelves.shelfname,owner,surname,firstname,virtualshelves.category,virtualshelves.sortfield,
102                count(virtualshelfcontents.biblionumber) as count
103         FROM   virtualshelves
104             LEFT JOIN   virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber
105             LEFT JOIN   borrowers ON virtualshelves.owner = borrowers.borrowernumber
106         WHERE  owner=? OR category>=?
107         GROUP BY virtualshelves.shelfnumber
108         ORDER BY virtualshelves.category, virtualshelves.shelfname, borrowers.firstname, borrowers.surname
109     );
110         $limit and $query .= " LIMIT $limit ";
111     my $sth = $dbh->prepare($query);
112     $sth->execute( $owner, $mincategory );
113     my %shelflist;
114     while (
115         my (
116             $shelfnumber, $shelfname, $owner, $surname,
117             $firstname,   $category,  $sortfield, $count
118         )
119         = $sth->fetchrow
120       )
121     {
122         $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
123         $shelflist{$shelfnumber}->{'count'}     = $count;
124         $shelflist{$shelfnumber}->{'sortfield'} = $sortfield;
125         $shelflist{$shelfnumber}->{'category'}  = $category;
126         $shelflist{$shelfnumber}->{'owner'}     = $owner;
127         $shelflist{$shelfnumber}->{'surname'}   = $surname;
128         $shelflist{$shelfnumber}->{'firstname'} = $firstname;
129     }
130     return ( \%shelflist );
131 }
132
133 sub GetShelvesSummary {
134     my ($owner, $mincategory, $limit) = @_;
135         ($mincategory and $mincategory =~ /^\d+$/) or $mincategory = 2;
136         (      $limit and       $limit =~ /^\d+$/) or $limit = 10;
137     my $query = qq(
138                 SELECT
139                         virtualshelves.shelfnumber,
140                         virtualshelves.shelfname,
141                         owner,
142                         CONCAT(firstname, ' ', surname) AS name,
143                         virtualshelves.category,
144                         count(virtualshelfcontents.biblionumber) AS count
145                 FROM   virtualshelves
146                         LEFT JOIN  virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber
147                         LEFT JOIN             borrowers ON virtualshelves.owner = borrowers.borrowernumber
148                 WHERE  owner=? OR category>=?
149                 GROUP BY virtualshelves.shelfnumber
150                 ORDER BY virtualshelves.category, borrowers.surname, borrowers.firstname, virtualshelves.shelfname
151                 LIMIT ?
152         );
153         my $sth = $dbh->prepare($query);
154         $sth->execute($owner,$mincategory,$limit);
155     return $sth->fetchall_arrayref({});
156         # Probably NOT the final implementation since it is still bulky (repeated hash keys).
157         # might like an array of rows of delimited values:
158         # 1|2||0|blacklist|112
159         # 2|6|Josh Ferraro|51|en_fuego|106
160 }
161
162 =item GetShelf
163
164   (shelfnumber,shelfname,owner,category) = &GetShelf($shelfnumber);
165
166 Looks up information about the contents of virtual virtualshelves number
167 C<$shelfnumber>
168
169 Returns the database's information on 'virtualshelves' table.
170
171 =cut
172
173 sub GetShelf {
174     my ($shelfnumber) = @_;
175     my $query = qq(
176         SELECT shelfnumber,shelfname,owner,category,sortfield
177         FROM   virtualshelves
178         WHERE  shelfnumber=?
179     );
180     my $sth = $dbh->prepare($query);
181     $sth->execute($shelfnumber);
182     return $sth->fetchrow;
183 }
184
185 =item GetShelfContents
186
187   $itemlist = &GetShelfContents($shelfnumber);
188
189 Looks up information about the contents of virtual virtualshelves number
190 C<$shelfnumber>.  Sorted by a field in the biblio table.  copyrightdate 
191 gives a desc sort.
192
193 Returns a reference-to-array, whose elements are references-to-hash,
194 as returned by C<C4::Biblio::GetBiblioFromItemNumber>.
195
196 Note: the notforloan status comes from the itemtype, and where it equals 0
197 it does not ensure that related items.notforloan status is likewise 0. The
198 caller has to check any items on their own, possibly with CanBookBeIssued
199 from C4::Circulation.
200
201 =cut
202
203 sub GetShelfContents {
204     my ( $shelfnumber ,$sortfield) = @_;
205     my $dbh=C4::Context->dbh();
206         if(!$sortfield) {
207                 my $sthsort = $dbh->prepare('select sortfield from virtualshelves where shelfnumber=?');
208                 $sthsort->execute($shelfnumber);
209                 ($sortfield) = $sthsort->fetchrow_array;
210         }
211     my $query =
212        " SELECT vc.biblionumber, vc.shelfnumber,
213                                 biblio.*, biblioitems.itemtype, itemtypes.*
214          FROM   virtualshelfcontents vc
215                  LEFT JOIN biblio      ON      vc.biblionumber =      biblio.biblionumber
216                  LEFT JOIN biblioitems ON  biblio.biblionumber = biblioitems.biblionumber
217                  LEFT JOIN itemtypes   ON biblioitems.itemtype = itemtypes.itemtype
218          WHERE  vc.shelfnumber=? ";
219         if($sortfield) {
220                 $query .= " ORDER BY `$sortfield` ";
221                 $query .= " DESC " if ($sortfield eq 'copyrightdate');
222         }
223     my $sth = $dbh->prepare($query);
224         $sth->execute($shelfnumber);
225         return $sth->fetchall_arrayref({});     
226         # Like the perldoc says,
227         # returns reference-to-array, where each element is reference-to-hash of the row:
228         #   like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ] 
229         # Suitable for use in TMPL_LOOP.
230         # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
231         # or newer, for your version of DBI.
232 }
233
234 =item AddShelf
235
236   $shelfnumber = &AddShelf( $shelfname, $owner, $category);
237
238 Creates a new virtual virtualshelves with name C<$shelfname>, owner C<$owner> and category
239 C<$category>.
240
241 Returns a code to know what's happen.
242     * -1 : if this virtualshelves already exist.
243     * $shelfnumber : if success.
244
245 =cut
246
247 sub AddShelf {
248     my ( $shelfname, $owner, $category ) = @_;
249     my $query = qq(
250         SELECT *
251         FROM   virtualshelves
252         WHERE  shelfname=? AND owner=?
253     );
254     my $sth = $dbh->prepare($query);
255     $sth->execute($shelfname,$owner);
256     ( $sth->rows ) and return (-1);
257     $query = qq(
258         INSERT INTO virtualshelves
259             (shelfname,owner,category)
260         VALUES (?,?,?)
261     );
262     $sth = $dbh->prepare($query);
263     $sth->execute( $shelfname, $owner, $category );
264     my $shelfnumber = $dbh->{'mysql_insertid'};
265     return ($shelfnumber);
266 }
267
268 =item AddToShelf
269
270   &AddToShelf($biblionumber, $shelfnumber);
271
272 Adds item number C<$biblionumber> to virtual virtualshelves number
273 C<$shelfnumber>, unless that item is already on that shelf.
274
275 =cut
276
277 #'
278 sub AddToShelf {
279     my ( $biblionumber, $shelfnumber ) = @_;
280     return unless $biblionumber;
281     my $query = qq(
282         SELECT *
283         FROM   virtualshelfcontents
284         WHERE  shelfnumber=? AND biblionumber=?
285     );
286     my $sth = $dbh->prepare($query);
287
288     $sth->execute( $shelfnumber, $biblionumber );
289     ($sth->rows) and return undef;      # already on shelf
290         $query = qq(
291                 INSERT INTO virtualshelfcontents
292                         (shelfnumber, biblionumber, flags)
293                 VALUES
294                         (?, ?, 0)
295         );
296         $sth = $dbh->prepare($query);
297         $sth->execute( $shelfnumber, $biblionumber );
298 }
299
300 =item AddToShelfFromBiblio
301  
302     &AddToShelfFromBiblio($biblionumber, $shelfnumber)
303
304     this function allow to add a virtual into the shelf number $shelfnumber
305     from biblionumber.
306
307 =cut
308
309 sub AddToShelfFromBiblio {
310     my ( $biblionumber, $shelfnumber ) = @_;
311     return unless $biblionumber;
312     my $query = qq(
313         SELECT *
314         FROM   virtualshelfcontents
315         WHERE  shelfnumber=? AND biblionumber=?
316     );
317     my $sth = $dbh->prepare($query);
318     $sth->execute( $shelfnumber, $biblionumber );
319     unless ( $sth->rows ) {
320         my $query =qq(
321             INSERT INTO virtualshelfcontents
322                 (shelfnumber, biblionumber, flags)
323             VALUES
324                 (?, ?, 0)
325         );
326         $sth = $dbh->prepare($query);
327         $sth->execute( $shelfnumber, $biblionumber );
328     }
329 }
330
331 =item ModShelf
332
333 ModShelf($shelfnumber, $shelfname, $owner, $category )
334
335 Modify the value into virtualshelves table with values given on input arg.
336
337 =cut
338
339 sub ModShelf {
340     my ( $shelfnumber, $shelfname, $owner, $category, $sortfield ) = @_;
341     my $query = qq(
342         UPDATE virtualshelves
343         SET    shelfname=?,owner=?,category=?,sortfield=?
344         WHERE  shelfnumber=?
345     );
346         my $sth = $dbh->prepare($query);
347     $sth->execute( $shelfname, $owner, $category, $sortfield, $shelfnumber );
348 }
349
350 =item ShelfPossibleAction
351
352 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
353
354 C<$loggedinuser,$shelfnumber,$action>
355
356 $action can be "view" or "manage".
357
358 Returns 1 if the user can do the $action in the $shelfnumber shelf.
359 Returns 0 otherwise.
360
361 =cut
362
363 sub ShelfPossibleAction {
364     my ( $user, $shelfnumber, $action ) = @_;
365     my $query = qq(
366         SELECT owner,category
367         FROM   virtualshelves
368         WHERE  shelfnumber=?
369     );
370     my $sth = $dbh->prepare($query);
371     $sth->execute($shelfnumber);
372     my ( $owner, $category ) = $sth->fetchrow;
373     return 1 if ($owner eq $user);
374     return 1 if ( $category >= 3);
375     return 1 if (($category >= 2) && $action eq 'view' );
376     return 0;
377 }
378
379 =item DelFromShelf
380
381   &DelFromShelf( $biblionumber, $shelfnumber);
382
383 Removes item number C<$biblionumber> from virtual virtualshelves number
384 C<$shelfnumber>. If the item wasn't on that virtualshelves to begin with,
385 nothing happens.
386
387 =cut
388
389 #'
390 sub DelFromShelf {
391     my ( $biblionumber, $shelfnumber ) = @_;
392     my $query = qq(
393         DELETE FROM virtualshelfcontents
394         WHERE  shelfnumber=? AND biblionumber=?
395     );
396     my $sth = $dbh->prepare($query);
397     $sth->execute( $shelfnumber, $biblionumber );
398 }
399
400 =item DelShelf (old version)
401
402   ($status, $msg) = &DelShelf($shelfnumber);
403
404 Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must
405 be empty.
406
407 Returns a two-element array, where C<$status> is 0 if the operation
408 was successful, or non-zero otherwise. C<$msg> is "Done" in case of
409 success, or an error message giving the reason for failure.
410
411 =item DelShelf (current version)
412
413   $Number = DelShelf($shelfnumber);
414
415 This function deletes the shelf number, and all of it's content.
416
417 =cut
418
419 sub DelShelf {
420         unless (@_) {
421                 carp "DelShelf called without valid argument (shelfnumber)";
422                 return undef;
423         }
424         my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
425         return $sth->execute(shift);
426 }
427
428 1;
429
430 __END__
431
432 =back
433
434 =head1 AUTHOR
435
436 Koha Developement team <info@koha.org>
437
438 =head1 SEE ALSO
439
440 C4::Circulation::Circ2(3)
441
442 =cut