← Index
NYTProf Performance Profile   « line view »
For svc/members/upsert
  Run on Tue Jan 13 11:50:22 2015
Reported on Tue Jan 13 12:09:51 2015

Filename/mnt/catalyst/koha/C4/VirtualShelves.pm
StatementsExecuted 26 statements in 1.95ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111418µs433µsC4::VirtualShelves::::BEGIN@20C4::VirtualShelves::BEGIN@20
11111µs19µsC4::VirtualShelves::::BEGIN@21C4::VirtualShelves::BEGIN@21
11111µs11µsC4::VirtualShelves::::BEGIN@34C4::VirtualShelves::BEGIN@34
1118µs36µsC4::VirtualShelves::::BEGIN@27C4::VirtualShelves::BEGIN@27
1118µs85µsC4::VirtualShelves::::BEGIN@25C4::VirtualShelves::BEGIN@25
1118µs37µsC4::VirtualShelves::::BEGIN@23C4::VirtualShelves::BEGIN@23
1117µs9µsC4::VirtualShelves::::BEGIN@24C4::VirtualShelves::BEGIN@24
1117µs53µsC4::VirtualShelves::::BEGIN@32C4::VirtualShelves::BEGIN@32
1117µs27µsC4::VirtualShelves::::BEGIN@28C4::VirtualShelves::BEGIN@28
1117µs26µsC4::VirtualShelves::::BEGIN@29C4::VirtualShelves::BEGIN@29
1116µs25µsC4::VirtualShelves::::BEGIN@30C4::VirtualShelves::BEGIN@30
0000s0sC4::VirtualShelves::::AddShelfC4::VirtualShelves::AddShelf
0000s0sC4::VirtualShelves::::AddToShelfC4::VirtualShelves::AddToShelf
0000s0sC4::VirtualShelves::::DelFromShelfC4::VirtualShelves::DelFromShelf
0000s0sC4::VirtualShelves::::DelShelfC4::VirtualShelves::DelShelf
0000s0sC4::VirtualShelves::::GetAllShelvesC4::VirtualShelves::GetAllShelves
0000s0sC4::VirtualShelves::::GetBibliosShelvesC4::VirtualShelves::GetBibliosShelves
0000s0sC4::VirtualShelves::::GetShelfC4::VirtualShelves::GetShelf
0000s0sC4::VirtualShelves::::GetShelfContentsC4::VirtualShelves::GetShelfContents
0000s0sC4::VirtualShelves::::GetShelvesC4::VirtualShelves::GetShelves
0000s0sC4::VirtualShelves::::GetSomeShelfNamesC4::VirtualShelves::GetSomeShelfNames
0000s0sC4::VirtualShelves::::HandleDelBorrowerC4::VirtualShelves::HandleDelBorrower
0000s0sC4::VirtualShelves::::ModShelfC4::VirtualShelves::ModShelf
0000s0sC4::VirtualShelves::::ShelfPossibleActionC4::VirtualShelves::ShelfPossibleAction
0000s0sC4::VirtualShelves::::ShelvesMaxC4::VirtualShelves::ShelvesMax
0000s0sC4::VirtualShelves::::_CheckShelfNameC4::VirtualShelves::_CheckShelfName
0000s0sC4::VirtualShelves::::_shelf_countC4::VirtualShelves::_shelf_count
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package C4::VirtualShelves;
2
3# Copyright 2000-2002 Katipo Communications
4#
5# This file is part of Koha.
6#
7# Koha is free software; you can redistribute it and/or modify it under the
8# terms of the GNU General Public License as published by the Free Software
9# Foundation; either version 2 of the License, or (at your option) any later
10# version.
11#
12# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with Koha; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20230µs2447µs
# spent 433µs (418+14) within C4::VirtualShelves::BEGIN@20 which was called: # once (418µs+14µs) by C4::Auth::BEGIN@31 at line 20
use strict;
# spent 433µs making 1 call to C4::VirtualShelves::BEGIN@20 # spent 14µs making 1 call to strict::import
21229µs227µs
# spent 19µs (11+8) within C4::VirtualShelves::BEGIN@21 which was called: # once (11µs+8µs) by C4::Auth::BEGIN@31 at line 21
use warnings;
# spent 19µs making 1 call to C4::VirtualShelves::BEGIN@21 # spent 8µs making 1 call to warnings::import
22
23222µs267µs
# spent 37µs (8+30) within C4::VirtualShelves::BEGIN@23 which was called: # once (8µs+30µs) by C4::Auth::BEGIN@31 at line 23
use Carp;
# spent 37µs making 1 call to C4::VirtualShelves::BEGIN@23 # spent 30µs making 1 call to Exporter::import
24219µs212µs
# spent 9µs (7+2) within C4::VirtualShelves::BEGIN@24 which was called: # once (7µs+2µs) by C4::Auth::BEGIN@31 at line 24
use C4::Context;
# spent 9µs making 1 call to C4::VirtualShelves::BEGIN@24 # spent 2µs making 1 call to C4::Context::import
25227µs2161µs
# spent 85µs (8+76) within C4::VirtualShelves::BEGIN@25 which was called: # once (8µs+76µs) by C4::Auth::BEGIN@31 at line 25
use C4::Debug;
# spent 85µs making 1 call to C4::VirtualShelves::BEGIN@25 # spent 76µs making 1 call to Exporter::import
26
27225µs263µs
# spent 36µs (8+27) within C4::VirtualShelves::BEGIN@27 which was called: # once (8µs+27µs) by C4::Auth::BEGIN@31 at line 27
use constant SHELVES_MASTHEAD_MAX => 10; #number under Lists button in masthead
# spent 36µs making 1 call to C4::VirtualShelves::BEGIN@27 # spent 27µs making 1 call to constant::import
28222µs248µs
# spent 27µs (7+20) within C4::VirtualShelves::BEGIN@28 which was called: # once (7µs+20µs) by C4::Auth::BEGIN@31 at line 28
use constant SHELVES_COMBO_MAX => 10; #add to combo in search
# spent 27µs making 1 call to C4::VirtualShelves::BEGIN@28 # spent 20µs making 1 call to constant::import
29224µs245µs
# spent 26µs (7+19) within C4::VirtualShelves::BEGIN@29 which was called: # once (7µs+19µs) by C4::Auth::BEGIN@31 at line 29
use constant SHELVES_MGRPAGE_MAX => 20; #managing page
# spent 26µs making 1 call to C4::VirtualShelves::BEGIN@29 # spent 19µs making 1 call to constant::import
30230µs244µs
# spent 25µs (6+19) within C4::VirtualShelves::BEGIN@30 which was called: # once (6µs+19µs) by C4::Auth::BEGIN@31 at line 30
use constant SHELVES_POPUP_MAX => 40; #addbybiblio popup
# spent 25µs making 1 call to C4::VirtualShelves::BEGIN@30 # spent 19µs making 1 call to constant::import
31
32261µs298µs
# spent 53µs (7+45) within C4::VirtualShelves::BEGIN@32 which was called: # once (7µs+45µs) by C4::Auth::BEGIN@31 at line 32
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
# spent 53µs making 1 call to C4::VirtualShelves::BEGIN@32 # spent 45µs making 1 call to vars::import
33
34
# spent 11µs within C4::VirtualShelves::BEGIN@34 which was called: # once (11µs+0s) by C4::Auth::BEGIN@31 at line 50
BEGIN {
35 # set the version for version checking
361800ns $VERSION = 3.07.00.049;
371500ns require Exporter;
3815µs @ISA = qw(Exporter);
391900ns @EXPORT = qw(
40 &GetShelves &GetShelfContents &GetShelf
41 &AddToShelf &AddShelf
42 &ModShelf
43 &ShelfPossibleAction
44 &DelFromShelf &DelShelf
45 &GetBibliosShelves
46 );
4714µs @EXPORT_OK = qw(
48 &GetAllShelves &ShelvesMax
49 );
5011.65ms111µs}
# spent 11µs making 1 call to C4::VirtualShelves::BEGIN@34
51
52
53=head1 NAME
54
55C4::VirtualShelves - Functions for manipulating Koha virtual shelves
56
57=head1 SYNOPSIS
58
59 use C4::VirtualShelves;
60
61=head1 DESCRIPTION
62
63This module provides functions for manipulating virtual shelves,
64including creating and deleting virtual shelves, and adding and removing
65bibs to and from virtual shelves.
66
67=head1 FUNCTIONS
68
69=head2 GetShelves
70
71 ($shelflist, $totshelves) = &GetShelves($category, $row_count, $offset, $owner);
72 ($shelfnumber, $shelfhash) = each %{$shelflist};
73
74Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total
75number of shelves that meet the C<$owner> and C<$category> criteria. C<$category>,
76C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$category> == 1.
77When C<$category> is 2, supply undef as argument for C<$owner>.
78
79This 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.
80
81C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above),
82and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys:
83
84=over
85
86=item C<$shelfhash-E<gt>{shelfname}>
87
88A string. The name of the shelf.
89
90=item C<$shelfhash-E<gt>{count}>
91
92The number of virtuals on that virtualshelves.
93
94=back
95
96=cut
97
98sub GetShelves {
99 my ($category, $row_count, $offset, $owner) = @_;
100 my @params;
101 my $total = _shelf_count($owner, $category);
102 my $dbh = C4::Context->dbh;
103 my $query = qq{
104 SELECT vs.shelfnumber, vs.shelfname,vs.owner,
105 bo.surname,bo.firstname,vs.category,vs.sortfield,
106 count(vc.biblionumber) as count
107 FROM virtualshelves vs
108 LEFT JOIN borrowers bo ON vs.owner=bo.borrowernumber
109 LEFT JOIN virtualshelfcontents vc USING (shelfnumber) };
110 if($category==1) {
111 $query.= qq{
112 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
113 AND sh.borrowernumber=?
114 WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
115 @params= ($owner, $owner, $owner, $offset||0, $row_count);
116 }
117 else {
118 $query.= 'WHERE category=2 ';
119 @params= ($offset||0, $row_count);
120 }
121 $query.= qq{
122 GROUP BY vs.shelfnumber
123 ORDER BY vs.shelfname
124 LIMIT ?, ?};
125
126 my $sth2 = $dbh->prepare($query);
127 $sth2->execute(@params);
128 my %shelflist;
129 while( my ($shelfnumber, $shelfname, $owner, $surname, $firstname, $category, $sortfield, $count)= $sth2->fetchrow) {
130 $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
131 $shelflist{$shelfnumber}->{'count'} = $count;
132 $shelflist{$shelfnumber}->{'single'} = $count==1;
133 $shelflist{$shelfnumber}->{'sortfield'} = $sortfield;
134 $shelflist{$shelfnumber}->{'category'} = $category;
135 $shelflist{$shelfnumber}->{'owner'} = $owner;
136 $shelflist{$shelfnumber}->{'surname'} = $surname;
137 $shelflist{$shelfnumber}->{'firstname'} = $firstname;
138 }
139 return ( \%shelflist, $total );
140}
141
142=head2 GetAllShelves
143
144 $shelflist = GetAllShelves($category, $owner)
145
146This function returns a reference to an array of hashrefs containing all shelves
147sorted by the shelf name.
148
149This function is intended to return a dataset reflecting all the shelves for
150the submitted parameters.
151
152=cut
153
154sub GetAllShelves {
155 my ($category,$owner,$adding_allowed) = @_;
156 my @params;
157 my $dbh = C4::Context->dbh;
158 my $query = 'SELECT vs.* FROM virtualshelves vs ';
159 if($category==1) {
160 $query.= qq{
161 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
162 AND sh.borrowernumber=?
163 WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
164 @params = ($owner, $owner, $owner);
165 }
166 else {
167 $query.='WHERE category=2 ';
168 @params = ();
169 }
170 $query.='AND (allow_add=1 OR owner=?) ' if $adding_allowed;
171 push @params, $owner if $adding_allowed;
172 $query.= 'ORDER BY shelfname ASC';
173 my $sth = $dbh->prepare( $query );
174 $sth->execute(@params);
175 return $sth->fetchall_arrayref({});
176}
177
178=head2 GetSomeShelfNames
179
180Returns shelf names and numbers for Add to combo of search results and Lists button of OPAC header.
181
182=cut
183
184sub GetSomeShelfNames {
185 my ($owner, $purpose, $adding_allowed)= @_;
186 my ($bar, $pub, @params);
187 my $dbh = C4::Context->dbh;
188
189 my $bquery = 'SELECT vs.shelfnumber, vs.shelfname FROM virtualshelves vs ';
190 my $limit= ShelvesMax($purpose);
191
192 my $qry1= $bquery."WHERE vs.category=2 ";
193 $qry1.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
194 push @params, $owner||0 if $adding_allowed;
195 $qry1.= "ORDER BY vs.lastmodified DESC LIMIT $limit";
196
197 unless($adding_allowed && (!defined($owner) || $owner<=0)) {
198 #if adding items, user should be known
199 $pub= $dbh->selectall_arrayref($qry1,{Slice=>{}},@params);
200 }
201
202 if($owner) {
203 my $qry2= $bquery. qq{
204 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber AND sh.borrowernumber=?
205 WHERE vs.category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
206 @params=($owner,$owner,$owner);
207 $qry2.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
208 push @params, $owner if $adding_allowed;
209 $qry2.= "ORDER BY vs.lastmodified DESC ";
210 $qry2.= "LIMIT $limit";
211 $bar= $dbh->selectall_arrayref($qry2,{Slice=>{}},@params);
212 }
213
214 return ( { bartotal => $bar? scalar @$bar: 0, pubtotal => $pub? scalar @$pub: 0}, $pub, $bar);
215}
216
217=head2 GetShelf
218
219 (shelfnumber,shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other) = &GetShelf($shelfnumber);
220
221Returns the above-mentioned fields for passed virtual shelf number.
222
223=cut
224
225sub GetShelf {
226 my ($shelfnumber) = @_;
227 my $dbh = C4::Context->dbh;
228 my $query = qq(
229 SELECT shelfnumber, shelfname, owner, category, sortfield,
230 allow_add, allow_delete_own, allow_delete_other
231 FROM virtualshelves
232 WHERE shelfnumber=?
233 );
234 my $sth = $dbh->prepare($query);
235 $sth->execute($shelfnumber);
236 return $sth->fetchrow;
237}
238
239=head2 GetShelfContents
240
241 $biblist = &GetShelfContents($shelfnumber);
242
243Looks up information about the contents of virtual virtualshelves number
244C<$shelfnumber>. Sorted by a field in the biblio table. copyrightdate
245gives a desc sort.
246
247Returns a reference-to-array, whose elements are references-to-hash,
248as returned by C<C4::Biblio::GetBiblioFromItemNumber>.
249
250Note: the notforloan status comes from the itemtype, and where it equals 0
251it does not ensure that related items.notforloan status is likewise 0. The
252caller has to check any items on their own, possibly with CanBookBeIssued
253from C4::Circulation.
254
255=cut
256
257sub GetShelfContents {
258 my ($shelfnumber, $row_count, $offset, $sortfield, $sort_direction ) = @_;
259 my $dbh=C4::Context->dbh();
260 my $sth1 = $dbh->prepare("SELECT count(*) FROM virtualshelfcontents WHERE shelfnumber = ?");
261 $sth1->execute($shelfnumber);
262 my $total = $sth1->fetchrow;
263 if(!$sortfield) {
264 my $sth2 = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?');
265 $sth2->execute($shelfnumber);
266 ($sortfield) = $sth2->fetchrow_array;
267 }
268 my $query =
269 " SELECT DISTINCT vc.biblionumber, vc.shelfnumber, vc.dateadded, itemtypes.*,
270 biblio.*, biblioitems.itemtype, biblioitems.publicationyear as year, biblioitems.publishercode, biblioitems.place, biblioitems.size, biblioitems.pages
271 FROM virtualshelfcontents vc
272 JOIN biblio ON vc.biblionumber = biblio.biblionumber
273 LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber
274 LEFT JOIN items ON items.biblionumber=vc.biblionumber
275 LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
276 WHERE vc.shelfnumber=? ";
277 my @params = ($shelfnumber);
278 if($sortfield) {
279 $query .= " ORDER BY " . $dbh->quote_identifier( $sortfield );
280 $query .= " DESC " if ( $sort_direction eq 'desc' );
281 }
282 if($row_count){
283 $query .= " LIMIT ?, ? ";
284 push (@params, ($offset ? $offset : 0));
285 push (@params, $row_count);
286 }
287 my $sth3 = $dbh->prepare($query);
288 $sth3->execute(@params);
289 return ($sth3->fetchall_arrayref({}), $total);
290 # Like the perldoc says,
291 # returns reference-to-array, where each element is reference-to-hash of the row:
292 # like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ]
293 # Suitable for use in TMPL_LOOP.
294 # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
295 # or newer, for your version of DBI.
296}
297
298=head2 AddShelf
299
300 $shelfnumber = &AddShelf($hashref, $owner);
301
302Creates a new virtual shelf. Params passed in a hash like ModShelf.
303
304Returns a code to know what's happen.
305 * -1 : if this virtualshelves already exists.
306 * $shelfnumber : if success.
307
308=cut
309
310sub AddShelf {
311 my ($hashref, $owner)= @_;
312 my $dbh = C4::Context->dbh;
313
314 #initialize missing hash values to silence warnings
315 foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
316 $hashref->{$_}= undef unless exists $hashref->{$_};
317 }
318
319 return -1 unless _CheckShelfName($hashref->{shelfname}, $hashref->{category}, $owner, 0);
320
321 my $query = qq(INSERT INTO virtualshelves
322 (shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other)
323 VALUES (?,?,?,?,?,?,?));
324
325 my $sth = $dbh->prepare($query);
326 $sth->execute(
327 $hashref->{shelfname},
328 $owner,
329 $hashref->{category},
330 $hashref->{sortfield},
331 $hashref->{allow_add}//0,
332 $hashref->{allow_delete_own}//1,
333 $hashref->{allow_delete_other}//0 );
334 my $shelfnumber = $dbh->{'mysql_insertid'};
335 return $shelfnumber;
336}
337
338=head2 AddToShelf
339
340 &AddToShelf($biblionumber, $shelfnumber, $borrower);
341
342Adds bib number C<$biblionumber> to virtual virtualshelves number
343C<$shelfnumber>, unless that bib is already on that shelf.
344
345=cut
346
347sub AddToShelf {
348 my ($biblionumber, $shelfnumber, $borrowernumber) = @_;
349 return unless $biblionumber;
350 my $dbh = C4::Context->dbh;
351 my $query = qq(
352 SELECT *
353 FROM virtualshelfcontents
354 WHERE shelfnumber=? AND biblionumber=?
355 );
356 my $sth = $dbh->prepare($query);
357
358 $sth->execute( $shelfnumber, $biblionumber );
359 ($sth->rows) and return; # already on shelf
360 $query = qq(
361 INSERT INTO virtualshelfcontents
362 (shelfnumber, biblionumber, flags, borrowernumber)
363 VALUES (?, ?, 0, ?));
364 $sth = $dbh->prepare($query);
365 $sth->execute( $shelfnumber, $biblionumber, $borrowernumber);
366 $query = qq(UPDATE virtualshelves
367 SET lastmodified = CURRENT_TIMESTAMP
368 WHERE shelfnumber = ?);
369 $sth = $dbh->prepare($query);
370 $sth->execute( $shelfnumber );
371}
372
373=head2 ModShelf
374
375my $result= ModShelf($shelfnumber, $hashref)
376
377Where $hashref->{column} = param
378
379Modify the value into virtualshelves table with values given
380from hashref, which each key of the hashref should be
381the name of a column of virtualshelves.
382Fields like shelfnumber or owner cannot be changed.
383
384Returns 1 if the action seemed to be successful.
385
386=cut
387
388sub ModShelf {
389 my ($shelfnumber,$hashref) = @_;
390 my $dbh = C4::Context->dbh;
391
392 my $query= "SELECT * FROM virtualshelves WHERE shelfnumber=?";
393 my $sth = $dbh->prepare($query);
394 $sth->execute($shelfnumber);
395 my $oldrecord= $sth->fetchrow_hashref;
396 return 0 unless $oldrecord; #not found?
397
398 #initialize missing hash values to silence warnings
399 foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
400 $hashref->{$_}= undef unless exists $hashref->{$_};
401 }
402
403 #if name or category changes, the name should be tested
404 if($hashref->{shelfname} || $hashref->{category}) {
405 unless(_CheckShelfName(
406 $hashref->{shelfname}//$oldrecord->{shelfname},
407 $hashref->{category}//$oldrecord->{category},
408 $oldrecord->{owner},
409 $shelfnumber )) {
410 return 0; #name check failed
411 }
412 }
413
414 #only the following fields from the hash may be changed
415 $query= "UPDATE virtualshelves SET shelfname=?, category=?, sortfield=?, allow_add=?, allow_delete_own=?, allow_delete_other=? WHERE shelfnumber=?";
416 $sth = $dbh->prepare($query);
417 $sth->execute(
418 $hashref->{shelfname}//$oldrecord->{shelfname},
419 $hashref->{category}//$oldrecord->{category},
420 $hashref->{sortfield}//$oldrecord->{sortfield},
421 $hashref->{allow_add}//$oldrecord->{allow_add},
422 $hashref->{allow_delete_own}//$oldrecord->{allow_delete_own},
423 $hashref->{allow_delete_other}//$oldrecord->{allow_delete_other},
424 $shelfnumber );
425 return $@? 0: 1;
426}
427
428=head2 ShelfPossibleAction
429
430ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
431
432C<$loggedinuser,$shelfnumber,$action>
433
434$action can be "view", "add", "delete", "manage", "new_public", "new_private".
435Note that add/delete here refers to adding/deleting entries from the list. Deleting the list itself falls under manage.
436new_public and new_private refers to creating a new public or private list.
437The distinction between deleting your own entries from the list or entries from
438others is made in DelFromShelf.
439
440Returns 1 if the user can do the $action in the $shelfnumber shelf.
441Returns 0 otherwise.
442
443=cut
444
445sub ShelfPossibleAction {
446 my ( $user, $shelfnumber, $action ) = @_;
447 $action= 'view' unless $action;
448 $user=0 unless $user;
449
450 if($action =~ /^new/) { #no shelfnumber needed
451 if($action eq 'new_private') {
452 return $user>0;
453 }
454 elsif($action eq 'new_public') {
455 return $user>0 && C4::Context->preference('OpacAllowPublicListCreation');
456 }
457 return 0;
458 }
459
460 return 0 unless defined($shelfnumber);
461
462 my $dbh = C4::Context->dbh;
463 my $query = qq/
464 SELECT COALESCE(owner,0) AS owner, category, allow_add, allow_delete_own, allow_delete_other, COALESCE(sh.borrowernumber,0) AS borrowernumber
465 FROM virtualshelves vs
466 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
467 AND sh.borrowernumber=?
468 WHERE vs.shelfnumber=?
469 /;
470 my $sth = $dbh->prepare($query);
471 $sth->execute($user, $shelfnumber);
472 my $shelf= $sth->fetchrow_hashref;
473
474 return 0 unless $shelf && ($shelf->{category}==2 || $shelf->{owner}==$user || ($user && $shelf->{borrowernumber}==$user));
475 if($action eq 'view') {
476 #already handled in the above condition
477 return 1;
478 }
479 elsif($action eq 'add') {
480 return 0 if $user<=0; #should be logged in
481 return 1 if $shelf->{allow_add}==1 || $shelf->{owner}==$user;
482 #owner may always add
483 }
484 elsif($action eq 'delete') {
485 #this answer is just diplomatic: it says that you may be able to delete
486 #some items from that shelf
487 #it does not answer the question about a specific biblio
488 #DelFromShelf checks the situation per biblio
489 return 1 if $user>0 && ($shelf->{allow_delete_own}==1 || $shelf->{allow_delete_other}==1);
490 }
491 elsif($action eq 'manage') {
492 return 1 if $user && $shelf->{owner}==$user;
493 }
494 return 0;
495}
496
497=head2 DelFromShelf
498
499 $result= &DelFromShelf( $bibref, $shelfnumber, $user);
500
501Removes biblionumbers in passed arrayref from shelf C<$shelfnumber>.
502If the bib wasn't on that virtualshelves to begin with, nothing happens.
503
504Returns 0 if no items have been deleted.
505
506=cut
507
508sub DelFromShelf {
509 my ($bibref, $shelfnumber, $user) = @_;
510 my $dbh = C4::Context->dbh;
511 my $query = qq(SELECT allow_delete_own, allow_delete_other FROM virtualshelves WHERE shelfnumber=?);
512 my $sth= $dbh->prepare($query);
513 $sth->execute($shelfnumber);
514 my ($del_own, $del_oth)= $sth->fetchrow;
515 my $r; my $t=0;
516
517 if($del_own) {
518 $query = qq(DELETE FROM virtualshelfcontents
519 WHERE shelfnumber=? AND biblionumber=? AND borrowernumber=?);
520 $sth= $dbh->prepare($query);
521 foreach my $biblionumber (@$bibref) {
522 $sth->execute($shelfnumber, $biblionumber, $user);
523 $r= $sth->rows; #Expect -1, 0 or 1 (-1 means Don't know; count as 1)
524 $t+= ($r==-1)? 1: $r;
525 }
526 }
527 if($del_oth) {
528 #includes a check if borrowernumber is null (deleted patron)
529 $query = qq/DELETE FROM virtualshelfcontents
530 WHERE shelfnumber=? AND biblionumber=? AND
531 (borrowernumber IS NULL OR borrowernumber<>?)/;
532 $sth= $dbh->prepare($query);
533 foreach my $biblionumber (@$bibref) {
534 $sth->execute($shelfnumber, $biblionumber, $user);
535 $r= $sth->rows;
536 $t+= ($r==-1)? 1: $r;
537 }
538 }
539 return $t;
540}
541
542=head2 DelShelf
543
544 $Number = DelShelf($shelfnumber);
545
546This function deletes the shelf number, and all of it's content.
547Authorization to do so MUST have been checked before calling, while using
548ShelfPossibleAction with manage parameter.
549
550=cut
551
552sub DelShelf {
553 my ($shelfnumber)= @_;
554 return unless $shelfnumber && $shelfnumber =~ /^\d+$/;
555 my $dbh = C4::Context->dbh;
556 my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
557 return $sth->execute($shelfnumber);
558}
559
560=head2 GetBibliosShelves
561
562This finds all the public lists that this bib record is in.
563
564=cut
565
566sub GetBibliosShelves {
567 my ( $biblionumber ) = @_;
568 my $dbh = C4::Context->dbh;
569 my $sth = $dbh->prepare('
570 SELECT vs.shelfname, vs.shelfnumber
571 FROM virtualshelves vs
572 JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber)
573 WHERE vs.category=2
574 AND vc.biblionumber= ?
575 ');
576 $sth->execute( $biblionumber );
577 return $sth->fetchall_arrayref({});
578}
579
580=head2 ShelvesMax
581
582 $howmany= ShelvesMax($context);
583
584Tells how much shelves are shown in which context.
585POPUP refers to addbybiblionumber popup, MGRPAGE is managing page (in opac or
586staff), COMBO refers to the Add to-combo of search results. MASTHEAD is the
587main Koha toolbar with Lists button.
588
589=cut
590
591sub ShelvesMax {
592 my $which= shift;
593 return SHELVES_POPUP_MAX if $which eq 'POPUP';
594 return SHELVES_MGRPAGE_MAX if $which eq 'MGRPAGE';
595 return SHELVES_COMBO_MAX if $which eq 'COMBO';
596 return SHELVES_MASTHEAD_MAX if $which eq 'MASTHEAD';
597 return SHELVES_MASTHEAD_MAX;
598}
599
600=head2 HandleDelBorrower
601
602 HandleDelBorrower($borrower);
603
604When a member is deleted (DelMember in Members.pm), you should call me first.
605This routine deletes/moves lists and entries for the deleted member/borrower.
606You could just delete everything (and lose more than you want), but instead we
607now try to save all public/shared stuff and keep others happy.
608
609=cut
610
611sub HandleDelBorrower {
612 my ($borrower)= @_;
613 my $query;
614 my $dbh = C4::Context->dbh;
615
616 #Delete shares of this borrower (not lists !)
617 #Although this would be done later via the FK cascaded delete, we do it now.
618 #Because it makes the following delete statement on shelves more meaningful.
619 $query="DELETE FROM virtualshelfshares WHERE borrowernumber=?";
620 $dbh->do($query,undef,($borrower));
621
622 #Delete private lists without owner that now have no shares anymore
623 $query="DELETE vs.* FROM virtualshelves vs LEFT JOIN virtualshelfshares sh USING (shelfnumber) WHERE category=1 AND vs.owner IS NULL AND sh.shelfnumber IS NULL";
624 $dbh->do($query);
625
626 #Change owner for private lists which have shares
627 $query="UPDATE virtualshelves LEFT JOIN virtualshelfshares sh USING (shelfnumber) SET owner=NULL where owner=? AND category=1 AND sh.borrowernumber IS NOT NULL";
628 $dbh->do($query,undef,($borrower));
629
630 #Delete unshared private lists
631 $query="DELETE FROM virtualshelves WHERE owner=? AND category=1";
632 $dbh->do($query,undef,($borrower));
633
634 #Handle public lists owned by borrower
635 $query="UPDATE virtualshelves SET owner=NULL WHERE owner=? AND category=2";
636 $dbh->do($query,undef,($borrower));
637
638 #Handle entries added by borrower to lists of others
639 $query="UPDATE virtualshelfcontents SET borrowernumber=NULL WHERE borrowernumber=?";
640 $dbh->do($query,undef,($borrower));
641}
642
643# internal subs
644
645sub _shelf_count {
646 my ($owner, $category) = @_;
647 my @params;
648 # Find out how many shelves total meet the submitted criteria...
649
650 my $dbh = C4::Context->dbh;
651 my $query = "SELECT count(*) FROM virtualshelves vs ";
652 if($category==1) {
653 $query.= qq{
654 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
655 AND sh.borrowernumber=?
656 WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
657 @params= ($owner, $owner, $owner);
658 }
659 else {
660 $query.='WHERE category=2';
661 @params= ();
662 }
663 my $sth = $dbh->prepare($query);
664 $sth->execute(@params);
665 my ($total)= $sth->fetchrow;
666 return $total;
667}
668
669sub _CheckShelfName {
670 my ($name, $cat, $owner, $number)= @_;
671
672 my $dbh = C4::Context->dbh;
673 my @pars;
674 my $query = qq(
675 SELECT DISTINCT shelfnumber
676 FROM virtualshelves
677 LEFT JOIN virtualshelfshares sh USING (shelfnumber)
678 WHERE shelfname=? AND shelfnumber<>?);
679 if($cat==1 && defined($owner)) {
680 $query.= ' AND (sh.borrowernumber=? OR owner=?) AND category=1';
681 @pars=($name, $number, $owner, $owner);
682 }
683 elsif($cat==1 && !defined($owner)) { #owner is null (exceptional)
684 $query.= ' AND owner IS NULL AND category=1';
685 @pars=($name, $number);
686 }
687 else { #public list
688 $query.= ' AND category=2';
689 @pars=($name, $number);
690 }
691 my $sth = $dbh->prepare($query);
692 $sth->execute(@pars);
693 return $sth->rows>0? 0: 1;
694}
695
69614µs1;
697
698__END__