1 package C4
::VirtualShelves
;
3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
28 use constant SHELVES_MASTHEAD_MAX
=> 10; #number under Lists button in masthead
29 use constant SHELVES_COMBO_MAX
=> 10; #add to combo in search
30 use constant SHELVES_MGRPAGE_MAX
=> 20; #managing page
31 use constant SHELVES_POPUP_MAX
=> 40; #addbybiblio popup
33 use constant SHARE_INVITATION_EXPIRY_DAYS
=> 14; #two weeks to accept
35 use vars
qw($VERSION @ISA @EXPORT @EXPORT_OK);
38 # set the version for version checking
39 $VERSION = 3.07.00.049;
43 &GetShelves &GetShelfContents &GetShelf
47 &DelFromShelf &DelShelf
49 &AddShare &AcceptShare &RemoveShare &IsSharedList
52 &GetAllShelves &ShelvesMax
59 C4::VirtualShelves - Functions for manipulating Koha virtual shelves
63 use C4::VirtualShelves;
67 This module provides functions for manipulating virtual shelves,
68 including creating and deleting virtual shelves, and adding and removing
69 bibs to and from virtual shelves.
75 $shelflist = &GetShelves($category, $row_count, $offset, $owner);
76 ($shelfnumber, $shelfhash) = each %{$shelflist};
78 Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total
79 number of shelves that meet the C<$owner> and C<$category> criteria. C<$category>,
80 C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$category> == 1.
81 When C<$category> is 2, supply undef as argument for C<$owner>.
83 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.
85 C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above),
86 and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys:
90 =item C<$shelfhash-E<gt>{shelfname}>
92 A string. The name of the shelf.
99 my ($category, $row_count, $offset, $owner) = @_;
101 my @params = ( $offset, $row_count );
102 my $dbh = C4
::Context
->dbh;
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
) };
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 unshift @params, ($owner) x
3;
118 $query.= 'WHERE category=2 ';
121 GROUP BY vs
.shelfnumber
122 ORDER BY vs
.shelfname
125 my $sth2 = $dbh->prepare($query);
126 $sth2->execute(@params);
128 while( my ($shelfnumber, $shelfname, $owner, $surname, $firstname, $category, $sortfield, $count)= $sth2->fetchrow) {
129 $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
130 $shelflist{$shelfnumber}->{'count'} = $count;
131 $shelflist{$shelfnumber}->{'single'} = $count==1;
132 $shelflist{$shelfnumber}->{'sortfield'} = $sortfield;
133 $shelflist{$shelfnumber}->{'category'} = $category;
134 $shelflist{$shelfnumber}->{'owner'} = $owner;
135 $shelflist{$shelfnumber}->{'surname'} = $surname;
136 $shelflist{$shelfnumber}->{'firstname'} = $firstname;
143 $shelflist = GetAllShelves($category, $owner)
145 This function returns a reference to an array of hashrefs containing all shelves
146 sorted by the shelf name.
148 This function is intended to return a dataset reflecting all the shelves for
149 the submitted parameters.
154 my ($category,$owner,$adding_allowed) = @_;
156 my $dbh = C4
::Context
->dbh;
157 my $query = 'SELECT vs.* FROM virtualshelves vs ';
160 LEFT JOIN virtualshelfshares sh ON sh
.shelfnumber
=vs
.shelfnumber
161 AND sh
.borrowernumber
=?
162 WHERE category
=1 AND
(vs
.owner
=? OR sh
.borrowernumber
=?
) };
163 @params = ($owner, $owner, $owner);
166 $query.='WHERE category=2 ';
169 $query.='AND (allow_add=1 OR owner=?) ' if $adding_allowed;
170 push @params, $owner if $adding_allowed;
171 $query.= 'ORDER BY shelfname ASC';
172 my $sth = $dbh->prepare( $query );
173 $sth->execute(@params);
174 return $sth->fetchall_arrayref({});
177 =head2 GetSomeShelfNames
179 Returns shelf names and numbers for Add to combo of search results and Lists button of OPAC header.
183 sub GetSomeShelfNames
{
184 my ($owner, $purpose, $adding_allowed)= @_;
185 my ($bar, $pub, @params);
186 my $dbh = C4
::Context
->dbh;
188 my $bquery = 'SELECT vs.shelfnumber, vs.shelfname FROM virtualshelves vs ';
189 my $limit= ShelvesMax
($purpose);
191 my $qry1= $bquery."WHERE vs.category=2 ";
192 $qry1.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
193 push @params, $owner||0 if $adding_allowed;
194 $qry1.= "ORDER BY vs.lastmodified DESC LIMIT $limit";
196 unless($adding_allowed && (!defined($owner) || $owner<=0)) {
197 #if adding items, user should be known
198 $pub= $dbh->selectall_arrayref($qry1,{Slice
=>{}},@params);
202 my $qry2= $bquery. qq{
203 LEFT JOIN virtualshelfshares sh ON sh
.shelfnumber
=vs
.shelfnumber AND sh
.borrowernumber
=?
204 WHERE vs
.category
=1 AND
(vs
.owner
=? OR sh
.borrowernumber
=?
) };
205 @params=($owner,$owner,$owner);
206 $qry2.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
207 push @params, $owner if $adding_allowed;
208 $qry2.= "ORDER BY vs.lastmodified DESC ";
209 $qry2.= "LIMIT $limit";
210 $bar= $dbh->selectall_arrayref($qry2,{Slice
=>{}},@params);
213 return ( { bartotal
=> $bar?
scalar @
$bar: 0, pubtotal
=> $pub?
scalar @
$pub: 0}, $pub, $bar);
218 (shelfnumber,shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other) = &GetShelf($shelfnumber);
220 Returns the above-mentioned fields for passed virtual shelf number.
225 my ($shelfnumber) = @_;
226 my $dbh = C4
::Context
->dbh;
228 SELECT shelfnumber
, shelfname
, owner
, category
, sortfield
,
229 allow_add
, allow_delete_own
, allow_delete_other
233 my $sth = $dbh->prepare($query);
234 $sth->execute($shelfnumber);
235 return $sth->fetchrow;
238 =head2 GetShelfContents
240 $biblist = &GetShelfContents($shelfnumber);
242 Looks up information about the contents of virtual virtualshelves number
243 C<$shelfnumber>. Sorted by a field in the biblio table. copyrightdate
246 Returns a reference-to-array, whose elements are references-to-hash,
247 as returned by C<C4::Biblio::GetBiblioFromItemNumber>.
249 Note: the notforloan status comes from the itemtype, and where it equals 0
250 it does not ensure that related items.notforloan status is likewise 0. The
251 caller has to check any items on their own, possibly with CanBookBeIssued
252 from C4::Circulation.
256 sub GetShelfContents
{
257 my ($shelfnumber, $row_count, $offset, $sortfield, $sort_direction ) = @_;
258 my $dbh=C4
::Context
->dbh();
259 my $sth1 = $dbh->prepare("SELECT count(*) FROM virtualshelfcontents WHERE shelfnumber = ?");
260 $sth1->execute($shelfnumber);
261 my $total = $sth1->fetchrow;
263 my $sth2 = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?');
264 $sth2->execute($shelfnumber);
265 ($sortfield) = $sth2->fetchrow_array;
268 " SELECT DISTINCT vc.biblionumber, vc.shelfnumber, vc.dateadded, itemtypes.*,
269 biblio.*, biblioitems.itemtype, biblioitems.publicationyear as year, biblioitems.publishercode, biblioitems.place, biblioitems.size, biblioitems.pages
270 FROM virtualshelfcontents vc
271 JOIN biblio ON vc.biblionumber = biblio.biblionumber
272 LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber
273 LEFT JOIN items ON items.biblionumber=vc.biblionumber
274 LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
275 WHERE vc.shelfnumber=? ";
276 my @params = ($shelfnumber);
278 $query .= " ORDER BY " . $dbh->quote_identifier( $sortfield );
279 $query .= " DESC " if ( $sort_direction eq 'desc' );
282 $query .= " LIMIT ?, ? ";
283 push (@params, ($offset ?
$offset : 0));
284 push (@params, $row_count);
286 my $sth3 = $dbh->prepare($query);
287 $sth3->execute(@params);
288 return ($sth3->fetchall_arrayref({}), $total);
289 # Like the perldoc says,
290 # returns reference-to-array, where each element is reference-to-hash of the row:
291 # like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ]
292 # Suitable for use in TMPL_LOOP.
293 # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
294 # or newer, for your version of DBI.
299 $shelfnumber = &AddShelf($hashref, $owner);
301 Creates a new virtual shelf. Params passed in a hash like ModShelf.
303 Returns a code to know what's happen.
304 * -1 : if this virtualshelves already exists.
305 * $shelfnumber : if success.
310 my ($hashref, $owner)= @_;
311 my $dbh = C4
::Context
->dbh;
313 #initialize missing hash values to silence warnings
314 foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
315 $hashref->{$_}= undef unless exists $hashref->{$_};
318 return -1 unless _CheckShelfName
($hashref->{shelfname
}, $hashref->{category
}, $owner, 0);
320 my $query = q
|INSERT INTO virtualshelves
321 (shelfname
,owner
,category
,sortfield
,allow_add
,allow_delete_own
,allow_delete_other
, created_on
)
322 VALUES
(?
,?
,?
,?
,?
,?
,?
, NOW
())
325 my $sth = $dbh->prepare($query);
327 $hashref->{shelfname
},
329 $hashref->{category
},
330 $hashref->{sortfield
},
331 $hashref->{allow_add
}//0,
332 $hashref->{allow_delete_own
}//1,
333 $hashref->{allow_delete_other
}//0 );
335 my $shelfnumber = $dbh->{'mysql_insertid'};
341 &AddToShelf($biblionumber, $shelfnumber, $borrower);
343 Adds bib number C<$biblionumber> to virtual virtualshelves number
344 C<$shelfnumber>, unless that bib is already on that shelf.
349 my ($biblionumber, $shelfnumber, $borrowernumber) = @_;
350 return unless $biblionumber;
351 my $dbh = C4
::Context
->dbh;
354 FROM virtualshelfcontents
355 WHERE shelfnumber
=? AND biblionumber
=?
357 my $sth = $dbh->prepare($query);
359 $sth->execute( $shelfnumber, $biblionumber );
360 ($sth->rows) and return; # already on shelf
362 INSERT INTO virtualshelfcontents
363 (shelfnumber
, biblionumber
, flags
, borrowernumber
)
364 VALUES
(?
, ?
, 0, ?
));
365 $sth = $dbh->prepare($query);
366 $sth->execute( $shelfnumber, $biblionumber, $borrowernumber);
367 $query = qq(UPDATE virtualshelves
368 SET lastmodified
= CURRENT_TIMESTAMP
369 WHERE shelfnumber
= ?
);
370 $sth = $dbh->prepare($query);
371 $sth->execute( $shelfnumber );
376 my $result= ModShelf($shelfnumber, $hashref)
378 Where $hashref->{column} = param
380 Modify the value into virtualshelves table with values given
381 from hashref, which each key of the hashref should be
382 the name of a column of virtualshelves.
383 Fields like shelfnumber or owner cannot be changed.
385 Returns 1 if the action seemed to be successful.
390 my ($shelfnumber,$hashref) = @_;
391 my $dbh = C4
::Context
->dbh;
393 my $query= "SELECT * FROM virtualshelves WHERE shelfnumber=?";
394 my $sth = $dbh->prepare($query);
395 $sth->execute($shelfnumber);
396 my $oldrecord= $sth->fetchrow_hashref;
397 return 0 unless $oldrecord; #not found?
399 #initialize missing hash values to silence warnings
400 foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
401 $hashref->{$_}= undef unless exists $hashref->{$_};
404 #if name or category changes, the name should be tested
405 if($hashref->{shelfname
} || $hashref->{category
}) {
406 unless(_CheckShelfName
(
407 $hashref->{shelfname
}//$oldrecord->{shelfname
},
408 $hashref->{category
}//$oldrecord->{category
},
411 return 0; #name check failed
415 #only the following fields from the hash may be changed
416 $query= "UPDATE virtualshelves SET shelfname=?, category=?, sortfield=?, allow_add=?, allow_delete_own=?, allow_delete_other=? WHERE shelfnumber=?";
417 $sth = $dbh->prepare($query);
419 $hashref->{shelfname
}//$oldrecord->{shelfname
},
420 $hashref->{category
}//$oldrecord->{category
},
421 $hashref->{sortfield
}//$oldrecord->{sortfield
},
422 $hashref->{allow_add
}//$oldrecord->{allow_add
},
423 $hashref->{allow_delete_own
}//$oldrecord->{allow_delete_own
},
424 $hashref->{allow_delete_other
}//$oldrecord->{allow_delete_other
},
429 =head2 ShelfPossibleAction
431 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
433 C<$loggedinuser,$shelfnumber,$action>
435 $action can be "view", "add", "delete", "manage", "new_public", "new_private".
436 New additional actions are: invite, acceptshare.
437 Note that add/delete here refers to adding/deleting entries from the list. Deleting the list itself falls under manage.
438 new_public and new_private refers to creating a new public or private list.
439 The distinction between deleting your own entries from the list or entries from
440 others is made in DelFromShelf.
442 Returns 1 if the user can do the $action in the $shelfnumber shelf.
444 For the actions invite and acceptshare a second errorcode is returned if the
445 result is false. See opac-shareshelf.pl
449 sub ShelfPossibleAction
{
450 my ( $user, $shelfnumber, $action ) = @_;
451 $action= 'view' unless $action;
452 $user=0 unless $user;
454 if($action =~ /^new/) { #no shelfnumber needed
455 if($action eq 'new_private') {
458 elsif($action eq 'new_public') {
459 return $user>0 && C4
::Context
->preference('OpacAllowPublicListCreation');
464 return 0 unless defined($shelfnumber);
466 if ( $user > 0 and $action eq 'delete_shelf' ) {
467 my $borrower = C4
::Members
::GetMember
( borrowernumber
=> $user );
470 if C4
::Auth
::haspermission
( $borrower->{userid
}, { shelves
=> 'delete_public_lists' } );
473 my $dbh = C4
::Context
->dbh;
475 SELECT COALESCE(owner,0) AS owner, category, allow_add, allow_delete_own, allow_delete_other, COALESCE(sh.borrowernumber,0) AS borrowernumber
476 FROM virtualshelves vs
477 LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
478 AND sh.borrowernumber=?
479 WHERE vs.shelfnumber=?
481 my $sth = $dbh->prepare($query);
482 $sth->execute($user, $shelfnumber);
483 my $shelf= $sth->fetchrow_hashref;
485 return 0 unless $shelf && ($shelf->{category
}==2 || $shelf->{owner
}==$user || ($user && $shelf->{borrowernumber
}==$user));
486 if($action eq 'view') {
487 #already handled in the above condition
490 elsif($action eq 'add') {
491 return 0 if $user<=0; #should be logged in
492 return 1 if $shelf->{allow_add
}==1 || $shelf->{owner
}==$user;
493 #owner may always add
495 elsif($action eq 'delete') {
496 #this answer is just diplomatic: it says that you may be able to delete
497 #some items from that shelf
498 #it does not answer the question about a specific biblio
499 #DelFromShelf checks the situation per biblio
500 return 1 if $user>0 && ($shelf->{allow_delete_own
}==1 || $shelf->{allow_delete_other
}==1);
502 elsif($action eq 'invite') {
503 #for sharing you must be the owner and the list must be private
504 if( $shelf->{category
}==1 ) {
505 return 1 if $shelf->{owner
}==$user;
506 return (0, 4); # code 4: should be owner
509 return (0, 5); # code 5: should be private list
512 elsif($action eq 'acceptshare') {
513 #the key for accepting is checked later in AcceptShare
514 #you must not be the owner, list must be private
515 if( $shelf->{category
}==1 ) {
516 return (0, 8) if $shelf->{owner
}==$user;
517 #code 8: should not be owner
521 return (0, 5); # code 5: should be private list
524 elsif($action eq 'manage' or $action eq 'delete_shelf') {
525 return 1 if $user && $shelf->{owner
}==$user;
532 $result= &DelFromShelf( $bibref, $shelfnumber, $user);
534 Removes biblionumbers in passed arrayref from shelf C<$shelfnumber>.
535 If the bib wasn't on that virtualshelves to begin with, nothing happens.
537 Returns 0 if no items have been deleted.
542 my ($bibref, $shelfnumber, $user) = @_;
543 my $dbh = C4
::Context
->dbh;
544 my $query = qq(SELECT allow_delete_own
, allow_delete_other FROM virtualshelves WHERE shelfnumber
=?
);
545 my $sth= $dbh->prepare($query);
546 $sth->execute($shelfnumber);
547 my ($del_own, $del_oth)= $sth->fetchrow;
551 $query = qq(DELETE FROM virtualshelfcontents
552 WHERE shelfnumber
=? AND biblionumber
=? AND borrowernumber
=?
);
553 $sth= $dbh->prepare($query);
554 foreach my $biblionumber (@
$bibref) {
555 $sth->execute($shelfnumber, $biblionumber, $user);
556 $r= $sth->rows; #Expect -1, 0 or 1 (-1 means Don't know; count as 1)
557 $t+= ($r==-1)?
1: $r;
561 #includes a check if borrowernumber is null (deleted patron)
562 $query = qq/DELETE FROM virtualshelfcontents
563 WHERE shelfnumber
=? AND biblionumber
=? AND
564 (borrowernumber IS NULL OR borrowernumber
<>?
)/;
565 $sth= $dbh->prepare($query);
566 foreach my $biblionumber (@
$bibref) {
567 $sth->execute($shelfnumber, $biblionumber, $user);
569 $t+= ($r==-1)?
1: $r;
577 $Number = DelShelf($shelfnumber);
579 This function deletes the shelf number, and all of it's content.
580 Authorization to do so MUST have been checked before calling, while using
581 ShelfPossibleAction with manage parameter.
586 my ($shelfnumber)= @_;
587 return unless $shelfnumber && $shelfnumber =~ /^\d+$/;
588 my $dbh = C4
::Context
->dbh;
589 my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
590 return $sth->execute($shelfnumber);
593 =head2 GetBibliosShelves
595 This finds all the public lists that this bib record is in.
599 sub GetBibliosShelves
{
600 my ( $biblionumber ) = @_;
601 my $dbh = C4
::Context
->dbh;
602 my $sth = $dbh->prepare('
603 SELECT vs.shelfname, vs.shelfnumber
604 FROM virtualshelves vs
605 JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber)
607 AND vc.biblionumber= ?
609 $sth->execute( $biblionumber );
610 return $sth->fetchall_arrayref({});
615 $howmany= ShelvesMax($context);
617 Tells how much shelves are shown in which context.
618 POPUP refers to addbybiblionumber popup, MGRPAGE is managing page (in opac or
619 staff), COMBO refers to the Add to-combo of search results. MASTHEAD is the
620 main Koha toolbar with Lists button.
626 return SHELVES_POPUP_MAX
if $which eq 'POPUP';
627 return SHELVES_MGRPAGE_MAX
if $which eq 'MGRPAGE';
628 return SHELVES_COMBO_MAX
if $which eq 'COMBO';
629 return SHELVES_MASTHEAD_MAX
if $which eq 'MASTHEAD';
630 return SHELVES_MASTHEAD_MAX
;
633 =head2 HandleDelBorrower
635 HandleDelBorrower($borrower);
637 When a member is deleted (DelMember in Members.pm), you should call me first.
638 This routine deletes/moves lists and entries for the deleted member/borrower.
639 Lists owned by the borrower are deleted, but entries from the borrower to
640 other lists are kept.
644 sub HandleDelBorrower
{
647 my $dbh = C4
::Context
->dbh;
649 #Delete all lists and all shares of this borrower
650 #Consistent with the approach Koha uses on deleting individual lists
651 #Note that entries in virtualshelfcontents added by this borrower to
652 #lists of others will be handled by a table constraint: the borrower
653 #is set to NULL in those entries.
654 $query="DELETE FROM virtualshelves WHERE owner=?";
655 $dbh->do($query,undef,($borrower));
658 #We could handle the above deletes via a constraint too.
659 #But a new BZ report 11889 has been opened to discuss another approach.
660 #Instead of deleting we could also disown lists (based on a pref).
661 #In that way we could save shared and public lists.
662 #The current table constraints support that idea now.
663 #This pref should then govern the results of other routines such as
669 AddShare($shelfnumber, $key);
671 Adds a share request to the virtualshelves table.
672 Authorization must have been checked, and a key must be supplied. See script
673 opac-shareshelf.pl for an example.
674 This request is not yet confirmed. So it has no borrowernumber, it does have an
680 my ($shelfnumber, $key)= @_;
681 return if !$shelfnumber || !$key;
683 my $dbh = C4
::Context
->dbh;
684 my $sql = "INSERT INTO virtualshelfshares (shelfnumber, invitekey, sharedate) VALUES (?, ?, NOW())";
685 $dbh->do($sql, undef, ($shelfnumber, $key));
691 my $result= AcceptShare($shelfnumber, $key, $borrowernumber);
693 Checks acceptation of a share request.
694 Key must be found for this shelf. Invitation must not have expired.
695 Returns true when accepted, false otherwise.
700 my ($shelfnumber, $key, $borrowernumber)= @_;
701 return if !$shelfnumber || !$key || !$borrowernumber;
704 my $dbh = C4
::Context
->dbh;
706 UPDATE virtualshelfshares
707 SET invitekey=NULL, sharedate=NOW(), borrowernumber=?
708 WHERE shelfnumber=? AND invitekey=? AND (sharedate + INTERVAL ? DAY) >NOW()
710 my $i= $dbh->do($sql, undef, ($borrowernumber, $shelfnumber, $key, SHARE_INVITATION_EXPIRY_DAYS
));
711 return if !defined($i) || !$i || $i eq '0E0'; #not found
717 my $bool= IsSharedList( $shelfnumber );
719 IsSharedList checks if a (private) list has shares.
720 Note that such a check would not be useful for public lists. A public list has
721 no shares, but is visible for anyone by nature..
722 Used to determine the list type in the display of Your lists (all private).
723 Returns boolean value.
728 my ($shelfnumber) = @_;
729 my $dbh = C4
::Context
->dbh;
730 my $sql="SELECT id FROM virtualshelfshares WHERE shelfnumber=? AND borrowernumber IS NOT NULL";
731 my $sth = $dbh->prepare($sql);
732 $sth->execute($shelfnumber);
733 my ($rv)= $sth->fetchrow_array;
739 RemoveShare( $user, $shelfnumber );
741 RemoveShare removes a share for specific shelf and borrower.
742 Returns true if a record could be deleted.
747 my ($user, $shelfnumber)= @_;
748 my $dbh = C4
::Context
->dbh;
750 DELETE FROM virtualshelfshares
751 WHERE borrowernumber=? AND shelfnumber=?
753 my $n= $dbh->do($sql,undef,($user, $shelfnumber));
754 return if !defined($n) || !$n || $n eq '0E0'; #nothing removed
760 my ($owner, $category) = @_;
762 # Find out how many shelves total meet the submitted criteria...
764 my $dbh = C4
::Context
->dbh;
765 my $query = "SELECT count(*) FROM virtualshelves vs ";
768 LEFT JOIN virtualshelfshares sh ON sh
.shelfnumber
=vs
.shelfnumber
769 AND sh
.borrowernumber
=?
770 WHERE category
=1 AND
(vs
.owner
=? OR sh
.borrowernumber
=?
) };
771 @params= ($owner, $owner, $owner);
774 $query.='WHERE category=2';
777 my $sth = $dbh->prepare($query);
778 $sth->execute(@params);
779 my ($total)= $sth->fetchrow;
784 sub _CheckShelfName
{
785 my ($name, $cat, $owner, $number)= @_;
787 my $dbh = C4
::Context
->dbh;
790 SELECT DISTINCT shelfnumber
792 LEFT JOIN virtualshelfshares sh USING
(shelfnumber
)
793 WHERE shelfname
=? AND shelfnumber
<>?
);
794 if($cat==1 && defined($owner)) {
795 $query.= ' AND (sh.borrowernumber=? OR owner=?) AND category=1';
796 @pars=($name, $number, $owner, $owner);
798 elsif($cat==1 && !defined($owner)) { #owner is null (exceptional)
799 $query.= ' AND owner IS NULL AND category=1';
800 @pars=($name, $number);
803 $query.= ' AND category=2';
804 @pars=($name, $number);
806 my $sth = $dbh->prepare($query);
807 $sth->execute(@pars);
808 return $sth->rows>0?
0: 1;
817 Koha Development Team <http://koha-community.org/>
821 C4::Circulation::Circ2(3)