|
Lines 28-33
use Carp;
Link Here
|
| 28 |
use C4::Context; |
28 |
use C4::Context; |
| 29 |
use C4::Debug; |
29 |
use C4::Debug; |
| 30 |
|
30 |
|
|
|
31 |
use constant SHELVES_MASTHEAD_MAX => 10; #number under Lists button in masthead |
| 32 |
use constant SHELVES_COMBO_MAX => 10; #add to combo in search |
| 33 |
use constant SHELVES_MGRPAGE_MAX => 20; #managing page |
| 34 |
use constant SHELVES_POPUP_MAX => 40; #addbybiblio popup |
| 35 |
|
| 31 |
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); |
36 |
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); |
| 32 |
|
37 |
|
| 33 |
BEGIN { |
38 |
BEGIN { |
|
Lines 44-51
BEGIN {
Link Here
|
| 44 |
&GetBibliosShelves |
49 |
&GetBibliosShelves |
| 45 |
); |
50 |
); |
| 46 |
@EXPORT_OK = qw( |
51 |
@EXPORT_OK = qw( |
| 47 |
&GetShelvesSummary &GetRecentShelves &GetAllShelves |
52 |
&GetAllShelves &ShelvesMax |
| 48 |
&RefreshShelvesSummary &SetShelvesLimit |
|
|
| 49 |
); |
53 |
); |
| 50 |
} |
54 |
} |
| 51 |
|
55 |
|
|
Lines 54-60
my $dbh = C4::Context->dbh;
Link Here
|
| 54 |
|
58 |
|
| 55 |
=head1 NAME |
59 |
=head1 NAME |
| 56 |
|
60 |
|
| 57 |
C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves |
61 |
C4::VirtualShelves - Functions for manipulating Koha virtual shelves |
| 58 |
|
62 |
|
| 59 |
=head1 SYNOPSIS |
63 |
=head1 SYNOPSIS |
| 60 |
|
64 |
|
|
Lines 62-82
C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves
Link Here
|
| 62 |
|
66 |
|
| 63 |
=head1 DESCRIPTION |
67 |
=head1 DESCRIPTION |
| 64 |
|
68 |
|
| 65 |
This module provides functions for manipulating virtual virtualshelves, |
69 |
This module provides functions for manipulating virtual shelves, |
| 66 |
including creating and deleting virtualshelves, and adding and removing |
70 |
including creating and deleting virtual shelves, and adding and removing |
| 67 |
bibs to and from virtualshelves. |
71 |
bibs to and from virtual shelves. |
| 68 |
|
72 |
|
| 69 |
=head1 FUNCTIONS |
73 |
=head1 FUNCTIONS |
| 70 |
|
74 |
|
| 71 |
=head2 GetShelves |
75 |
=head2 GetShelves |
| 72 |
|
76 |
|
| 73 |
($shelflist, $totshelves) = &GetShelves($mincategory, $row_count, $offset, $owner); |
77 |
($shelflist, $totshelves) = &GetShelves($category, $row_count, $offset, $owner); |
| 74 |
($shelfnumber, $shelfhash) = each %{$shelflist}; |
78 |
($shelfnumber, $shelfhash) = each %{$shelflist}; |
| 75 |
|
79 |
|
| 76 |
Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total |
80 |
Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total |
| 77 |
number of shelves that meet the C<$owner> and C<$mincategory> criteria. C<$mincategory>, |
81 |
number of shelves that meet the C<$owner> and C<$category> criteria. C<$category>, |
| 78 |
C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1. |
82 |
C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$category> == 1. |
| 79 |
When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>. |
83 |
When C<$category> is 2, supply undef as argument for C<$owner>. |
|
|
84 |
|
| 85 |
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. |
| 86 |
|
| 80 |
C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above), |
87 |
C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above), |
| 81 |
and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys: |
88 |
and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys: |
| 82 |
|
89 |
|
|
Lines 94-128
The number of virtuals on that virtualshelves.
Link Here
|
| 94 |
|
101 |
|
| 95 |
=cut |
102 |
=cut |
| 96 |
|
103 |
|
| 97 |
sub GetShelves ($$$$) { |
104 |
sub GetShelves { |
| 98 |
my ($mincategory, $row_count, $offset, $owner) = @_; |
105 |
my ($category, $row_count, $offset, $owner) = @_; |
| 99 |
my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count); |
106 |
my @params; |
| 100 |
my @params1 = ($owner, $mincategory); |
107 |
my $total = _shelf_count($owner, $category); |
| 101 |
if ($mincategory > 1) { |
108 |
my $query = qq{ |
| 102 |
shift @params; |
109 |
SELECT vs.shelfnumber, vs.shelfname,vs.owner, |
| 103 |
shift @params1; |
110 |
bo.surname,bo.firstname,vs.category,vs.sortfield, |
| 104 |
} |
111 |
count(vc.biblionumber) as count |
| 105 |
my $total = _shelf_count($owner, $mincategory); |
112 |
FROM virtualshelves vs |
| 106 |
# grab only the shelves meeting the row_count/offset spec... |
113 |
LEFT JOIN borrowers bo ON vs.owner=bo.borrowernumber |
| 107 |
my $query = qq( |
114 |
LEFT JOIN virtualshelfcontents vc USING (shelfnumber) }; |
| 108 |
SELECT virtualshelves.shelfnumber, virtualshelves.shelfname,owner,surname,firstname,virtualshelves.category,virtualshelves.sortfield, |
115 |
if($category==1) { |
| 109 |
count(virtualshelfcontents.biblionumber) as count |
116 |
$query.= qq{ |
| 110 |
FROM virtualshelves |
117 |
LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber |
| 111 |
LEFT JOIN virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber |
118 |
AND sh.borrowernumber=? |
| 112 |
LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber ); |
119 |
WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; |
| 113 |
$query .= ($mincategory == 1) ? "WHERE owner=? AND category=?" : "WHERE category>=?"; |
120 |
@params= ($owner, $owner, $owner, $offset||0, $row_count); |
| 114 |
$query .= qq( |
121 |
} |
| 115 |
GROUP BY virtualshelves.shelfnumber |
122 |
else { |
| 116 |
ORDER BY virtualshelves.shelfname |
123 |
$query.= 'WHERE category=2 '; |
| 117 |
LIMIT ?, ?); |
124 |
@params= ($offset||0, $row_count); |
|
|
125 |
} |
| 126 |
$query.= qq{ |
| 127 |
GROUP BY vs.shelfnumber |
| 128 |
ORDER BY vs.shelfname |
| 129 |
LIMIT ?, ?}; |
| 130 |
|
| 118 |
my $sth2 = $dbh->prepare($query); |
131 |
my $sth2 = $dbh->prepare($query); |
| 119 |
$sth2->execute(@params); |
132 |
$sth2->execute(@params); |
| 120 |
my %shelflist; |
133 |
my %shelflist; |
| 121 |
while ( my ( $shelfnumber, $shelfname, $owner, $surname, |
134 |
while( my ($shelfnumber, $shelfname, $owner, $surname, $firstname, $category, $sortfield, $count)= $sth2->fetchrow) { |
| 122 |
$firstname, $category, $sortfield, $count ) = $sth2->fetchrow ) { |
|
|
| 123 |
$shelflist{$shelfnumber}->{'shelfname'} = $shelfname; |
135 |
$shelflist{$shelfnumber}->{'shelfname'} = $shelfname; |
| 124 |
$shelflist{$shelfnumber}->{'count'} = $count; |
136 |
$shelflist{$shelfnumber}->{'count'} = $count; |
| 125 |
if($count eq 1){ $shelflist{$shelfnumber}->{'single'} = 1; } |
137 |
$shelflist{$shelfnumber}->{'single'} = $count==1; |
| 126 |
$shelflist{$shelfnumber}->{'sortfield'} = $sortfield; |
138 |
$shelflist{$shelfnumber}->{'sortfield'} = $sortfield; |
| 127 |
$shelflist{$shelfnumber}->{'category'} = $category; |
139 |
$shelflist{$shelfnumber}->{'category'} = $category; |
| 128 |
$shelflist{$shelfnumber}->{'owner'} = $owner; |
140 |
$shelflist{$shelfnumber}->{'owner'} = $owner; |
|
Lines 132-242
sub GetShelves ($$$$) {
Link Here
|
| 132 |
return ( \%shelflist, $total ); |
144 |
return ( \%shelflist, $total ); |
| 133 |
} |
145 |
} |
| 134 |
|
146 |
|
| 135 |
=head2 GetShelvesSummary |
147 |
=head2 GetAllShelves |
| 136 |
|
|
|
| 137 |
($shelves, $total) = GetShelvesSummary($mincategory, $row_count, $offset, $owner) |
| 138 |
|
| 139 |
Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total |
| 140 |
number of shelves that meet the C<$owner> and/or C<$mincategory> criteria. C<$mincategory>, |
| 141 |
C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1. |
| 142 |
When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>. |
| 143 |
|
| 144 |
=cut |
| 145 |
|
| 146 |
sub GetShelvesSummary ($$$$) { |
| 147 |
my ($mincategory, $row_count, $offset, $owner) = @_; |
| 148 |
my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count); |
| 149 |
my @params1 = ($owner, $mincategory); |
| 150 |
if ($mincategory > 1) { |
| 151 |
shift @params; |
| 152 |
shift @params1; |
| 153 |
} |
| 154 |
my $total = _shelf_count($owner, $mincategory); |
| 155 |
# grab only the shelves meeting the row_count/offset spec... |
| 156 |
my $query = qq( |
| 157 |
SELECT |
| 158 |
virtualshelves.shelfnumber, |
| 159 |
virtualshelves.shelfname, |
| 160 |
owner, |
| 161 |
CONCAT(firstname, ' ', surname) AS name, |
| 162 |
virtualshelves.category, |
| 163 |
count(virtualshelfcontents.biblionumber) AS count |
| 164 |
FROM virtualshelves |
| 165 |
LEFT JOIN virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber |
| 166 |
LEFT JOIN borrowers ON virtualshelves.owner = borrowers.borrowernumber ); |
| 167 |
$query .= ($mincategory == 1) ? "WHERE owner=? AND category=?" : "WHERE category>=?"; |
| 168 |
$query .= qq( |
| 169 |
GROUP BY virtualshelves.shelfnumber |
| 170 |
ORDER BY virtualshelves.category |
| 171 |
DESC |
| 172 |
LIMIT ?, ?); |
| 173 |
my $sth2 = $dbh->prepare($query); |
| 174 |
$sth2->execute(@params); |
| 175 |
my $shelves = $sth2->fetchall_arrayref({}); |
| 176 |
return ($shelves, $total); |
| 177 |
|
| 178 |
# Probably NOT the final implementation since it is still bulky (repeated hash keys). |
| 179 |
# might like an array of rows of delimited values: |
| 180 |
# 1|2||0|blacklist|112 |
| 181 |
# 2|6|Josh Ferraro|51|en_fuego|106 |
| 182 |
} |
| 183 |
|
| 184 |
=head2 GetRecentShelves |
| 185 |
|
148 |
|
| 186 |
($shelflist, $total) = GetRecentShelves(1, $limit, $owner) |
149 |
$shelflist = GetAllShelves($category, $owner) |
| 187 |
|
150 |
|
| 188 |
This function returns a reference to an array of hashrefs containing specified shelves sorted |
151 |
This function returns a reference to an array of hashrefs containing all shelves |
| 189 |
by the date the shelf was last modified in descending order limited to the number of records |
152 |
sorted by the shelf name. |
| 190 |
specified by C<$row_count>. If calling with C<$mincategory> other than 1, use undef as C<$owner>. |
|
|
| 191 |
|
153 |
|
| 192 |
This function is intended to return a dataset reflecting the most recently active shelves for |
154 |
This function is intended to return a dataset reflecting all the shelves for |
| 193 |
the submitted parameters. |
155 |
the submitted parameters. |
| 194 |
|
156 |
|
| 195 |
=cut |
157 |
=cut |
| 196 |
|
158 |
|
| 197 |
sub GetRecentShelves { |
159 |
sub GetAllShelves { |
| 198 |
my ($mincategory, $row_count, $owner) = @_; |
160 |
my ($category,$owner,$adding_allowed) = @_; |
| 199 |
my $total = _shelf_count($owner, $mincategory); |
|
|
| 200 |
my @params; |
161 |
my @params; |
| 201 |
my $selection; |
162 |
my $query = 'SELECT vs.* FROM virtualshelves vs '; |
| 202 |
if (defined $owner) { |
163 |
if($category==1) { |
| 203 |
@params = ($owner, $mincategory); |
164 |
$query.= qq{ |
| 204 |
$selection = ' WHERE owner = ? AND category = ?'; |
165 |
LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber |
| 205 |
} else { |
166 |
AND sh.borrowernumber=? |
| 206 |
@params = ( $mincategory); |
167 |
WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; |
| 207 |
$selection = ' WHERE category >= ? '; |
168 |
@params = ($owner, $owner, $owner); |
| 208 |
} |
169 |
} |
| 209 |
my $query = 'SELECT * FROM virtualshelves'; |
170 |
else { |
| 210 |
$query .= $selection; |
171 |
$query.='WHERE category=2 '; |
| 211 |
$query .= ' ORDER BY lastmodified DESC'; |
172 |
@params = (); |
| 212 |
if ($row_count){ |
|
|
| 213 |
$query .= ' LIMIT ?'; |
| 214 |
push @params,$row_count; |
| 215 |
} |
173 |
} |
| 216 |
my $sth = $dbh->prepare($query); |
174 |
$query.='AND (allow_add=1 OR owner=?) ' if $adding_allowed; |
|
|
175 |
push @params, $owner if $adding_allowed; |
| 176 |
$query.= 'ORDER BY shelfname ASC'; |
| 177 |
my $sth = $dbh->prepare( $query ); |
| 217 |
$sth->execute(@params); |
178 |
$sth->execute(@params); |
| 218 |
my $shelflist = $sth->fetchall_arrayref({}); |
179 |
return $sth->fetchall_arrayref({}); |
| 219 |
return ( $shelflist, $total ); |
|
|
| 220 |
} |
180 |
} |
| 221 |
|
181 |
|
| 222 |
=head2 GetAllShelves |
182 |
=head2 GetSomeShelfNames |
| 223 |
|
183 |
|
| 224 |
$shelflist = GetAllShelves($owner) |
184 |
Returns shelf names and numbers for Add to combo of search results and Lists button of OPAC header. |
| 225 |
|
185 |
|
| 226 |
This function returns a reference to an array of hashrefs containing all shelves sorted |
186 |
=cut |
| 227 |
by the shelf name. |
|
|
| 228 |
|
187 |
|
| 229 |
This function is intended to return a dataset reflecting all the shelves for |
188 |
sub GetSomeShelfNames { |
| 230 |
the submitted parameters. |
189 |
my ($owner, $purpose, $adding_allowed)= @_; |
|
|
190 |
my ($bar, $pub, @params); |
| 231 |
|
191 |
|
| 232 |
=cut |
192 |
my $bquery = 'SELECT vs.shelfnumber, vs.shelfname FROM virtualshelves vs '; |
|
|
193 |
my $limit= ShelvesMax($purpose); |
| 233 |
|
194 |
|
| 234 |
sub GetAllShelves { |
195 |
my $qry1= $bquery."WHERE vs.category=2 "; |
| 235 |
my ($category,$owner) = @_; |
196 |
$qry1.= "AND (allow_add=1 OR owner=?) " if $adding_allowed; |
| 236 |
my $query = 'SELECT * FROM virtualshelves WHERE category = ? AND owner = ? ORDER BY shelfname ASC'; |
197 |
push @params, $owner||0 if $adding_allowed; |
| 237 |
my $sth = $dbh->prepare( $query ); |
198 |
$qry1.= "ORDER BY vs.lastmodified DESC LIMIT $limit"; |
| 238 |
$sth->execute( $category, $owner ); |
199 |
|
| 239 |
return $sth->fetchall_arrayref({}); |
200 |
unless($adding_allowed && (!defined($owner) || $owner<=0)) { |
|
|
201 |
#if adding items, user should be known |
| 202 |
$pub= $dbh->selectall_arrayref($qry1,{Slice=>{}},@params); |
| 203 |
} |
| 204 |
|
| 205 |
if($owner) { |
| 206 |
my $qry2= $bquery. qq{ |
| 207 |
LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber AND sh.borrowernumber=? |
| 208 |
WHERE vs.category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; |
| 209 |
@params=($owner,$owner,$owner); |
| 210 |
$qry2.= "AND (allow_add=1 OR owner=?) " if $adding_allowed; |
| 211 |
push @params, $owner if $adding_allowed; |
| 212 |
$qry2.= "ORDER BY vs.lastmodified DESC "; |
| 213 |
$qry2.= "LIMIT $limit"; |
| 214 |
$bar= $dbh->selectall_arrayref($qry2,{Slice=>{}},@params); |
| 215 |
} |
| 216 |
|
| 217 |
return ( { bartotal => $bar? scalar @$bar: 0, pubtotal => $pub? scalar @$pub: 0}, $pub, $bar); |
| 240 |
} |
218 |
} |
| 241 |
|
219 |
|
| 242 |
=head2 GetShelf |
220 |
=head2 GetShelf |
|
Lines 322-371
sub GetShelfContents ($;$$$) {
Link Here
|
| 322 |
|
300 |
|
| 323 |
=head2 AddShelf |
301 |
=head2 AddShelf |
| 324 |
|
302 |
|
| 325 |
$shelfnumber = &AddShelf( $shelfname, $owner, $category); |
303 |
$shelfnumber = &AddShelf($hashref, $owner); |
| 326 |
|
304 |
|
| 327 |
Creates a new virtual virtualshelves with name C<$shelfname>, owner C<$owner> and category |
305 |
Creates a new virtual shelf. Params passed in a hash like ModShelf. |
| 328 |
C<$category>. |
|
|
| 329 |
|
306 |
|
| 330 |
Returns a code to know what's happen. |
307 |
Returns a code to know what's happen. |
| 331 |
* -1 : if this virtualshelves already exist. |
308 |
* -1 : if this virtualshelves already exists. |
| 332 |
* $shelfnumber : if success. |
309 |
* $shelfnumber : if success. |
| 333 |
|
310 |
|
| 334 |
=cut |
311 |
=cut |
| 335 |
|
312 |
|
| 336 |
sub AddShelf { |
313 |
sub AddShelf { |
| 337 |
my ( $shelfname, $owner, $category, $sortfield ) = @_; |
314 |
my ($hashref, $owner)= @_; |
| 338 |
my $query = qq( |
315 |
|
| 339 |
SELECT * |
316 |
#initialize missing hash values to silence warnings |
| 340 |
FROM virtualshelves |
317 |
foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) { |
| 341 |
WHERE shelfname=? AND owner=? |
318 |
$hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': ''; |
| 342 |
); |
319 |
} |
|
|
320 |
|
| 321 |
return -1 unless _CheckShelfName($hashref->{shelfname}, $hashref->{category}, $owner, 0); |
| 322 |
|
| 323 |
my $query = qq(INSERT INTO virtualshelves |
| 324 |
(shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other) |
| 325 |
VALUES (?,?,?,?,?,?,?)); |
| 326 |
|
| 343 |
my $sth = $dbh->prepare($query); |
327 |
my $sth = $dbh->prepare($query); |
| 344 |
$sth->execute($shelfname,$owner); |
328 |
$sth->execute( |
| 345 |
( $sth->rows ) and return (-1); |
329 |
$hashref->{shelfname}, |
| 346 |
$query = qq( |
330 |
$owner, |
| 347 |
INSERT INTO virtualshelves |
331 |
$hashref->{category}, |
| 348 |
(shelfname,owner,category,sortfield) |
332 |
$hashref->{sortfield}, |
| 349 |
VALUES (?,?,?,?) |
333 |
$hashref->{allow_add}||0, |
| 350 |
); |
334 |
$hashref->{allow_delete_own}||1, |
| 351 |
$sth = $dbh->prepare($query); |
335 |
$hashref->{allow_delete_other}||0 ); |
| 352 |
$sth->execute( $shelfname, $owner, $category, $sortfield ); |
|
|
| 353 |
my $shelfnumber = $dbh->{'mysql_insertid'}; |
336 |
my $shelfnumber = $dbh->{'mysql_insertid'}; |
| 354 |
return ($shelfnumber); |
337 |
return $shelfnumber; |
| 355 |
} |
338 |
} |
| 356 |
|
339 |
|
| 357 |
=head2 AddToShelf |
340 |
=head2 AddToShelf |
| 358 |
|
341 |
|
| 359 |
&AddToShelf($biblionumber, $shelfnumber); |
342 |
&AddToShelf($biblionumber, $shelfnumber, $borrower); |
| 360 |
|
343 |
|
| 361 |
Adds bib number C<$biblionumber> to virtual virtualshelves number |
344 |
Adds bib number C<$biblionumber> to virtual virtualshelves number |
| 362 |
C<$shelfnumber>, unless that bib is already on that shelf. |
345 |
C<$shelfnumber>, unless that bib is already on that shelf. |
| 363 |
|
346 |
|
| 364 |
=cut |
347 |
=cut |
| 365 |
|
348 |
|
| 366 |
#' |
|
|
| 367 |
sub AddToShelf { |
349 |
sub AddToShelf { |
| 368 |
my ( $biblionumber, $shelfnumber ) = @_; |
350 |
my ($biblionumber, $shelfnumber, $borrowernumber) = @_; |
| 369 |
return unless $biblionumber; |
351 |
return unless $biblionumber; |
| 370 |
my $query = qq( |
352 |
my $query = qq( |
| 371 |
SELECT * |
353 |
SELECT * |
|
Lines 378-389
sub AddToShelf {
Link Here
|
| 378 |
($sth->rows) and return undef; # already on shelf |
360 |
($sth->rows) and return undef; # already on shelf |
| 379 |
$query = qq( |
361 |
$query = qq( |
| 380 |
INSERT INTO virtualshelfcontents |
362 |
INSERT INTO virtualshelfcontents |
| 381 |
(shelfnumber, biblionumber, flags) |
363 |
(shelfnumber, biblionumber, flags, borrowernumber) |
| 382 |
VALUES |
364 |
VALUES (?, ?, 0, ?)); |
| 383 |
(?, ?, 0) |
|
|
| 384 |
); |
| 385 |
$sth = $dbh->prepare($query); |
365 |
$sth = $dbh->prepare($query); |
| 386 |
$sth->execute( $shelfnumber, $biblionumber ); |
366 |
$sth->execute( $shelfnumber, $biblionumber, $borrowernumber); |
| 387 |
$query = qq(UPDATE virtualshelves |
367 |
$query = qq(UPDATE virtualshelves |
| 388 |
SET lastmodified = CURRENT_TIMESTAMP |
368 |
SET lastmodified = CURRENT_TIMESTAMP |
| 389 |
WHERE shelfnumber = ?); |
369 |
WHERE shelfnumber = ?); |
|
Lines 393-443
sub AddToShelf {
Link Here
|
| 393 |
|
373 |
|
| 394 |
=head2 ModShelf |
374 |
=head2 ModShelf |
| 395 |
|
375 |
|
| 396 |
ModShelf($shelfnumber, $hashref) |
376 |
my $result= ModShelf($shelfnumber, $hashref) |
| 397 |
|
377 |
|
| 398 |
Where $hashref->{column} = param |
378 |
Where $hashref->{column} = param |
| 399 |
|
379 |
|
| 400 |
Modify the value into virtualshelves table with values given |
380 |
Modify the value into virtualshelves table with values given |
| 401 |
from hashref, which each key of the hashref should be |
381 |
from hashref, which each key of the hashref should be |
| 402 |
the name of a column of virtualshelves. |
382 |
the name of a column of virtualshelves. |
|
|
383 |
Fields like shelfnumber or owner cannot be changed. |
| 384 |
|
| 385 |
Returns 1 if the action seemed to be successful. |
| 403 |
|
386 |
|
| 404 |
=cut |
387 |
=cut |
| 405 |
|
388 |
|
| 406 |
sub ModShelf { |
389 |
sub ModShelf { |
| 407 |
my $shelfnumber = shift; |
390 |
my ($shelfnumber,$hashref) = @_; |
| 408 |
my $shelf = shift; |
|
|
| 409 |
|
| 410 |
if (exists $shelf->{shelfnumber}) { |
| 411 |
carp "Should not use ModShelf to change shelfnumber"; |
| 412 |
return; |
| 413 |
} |
| 414 |
unless (defined $shelfnumber and $shelfnumber =~ /^\d+$/) { |
| 415 |
carp "Invalid shelfnumber passed to ModShelf: $shelfnumber"; |
| 416 |
return; |
| 417 |
} |
| 418 |
|
391 |
|
| 419 |
my $query = "UPDATE virtualshelves SET "; |
392 |
my $query= "SELECT * FROM virtualshelves WHERE shelfnumber=?"; |
| 420 |
my @bind_params = (); |
393 |
my $sth = $dbh->prepare($query); |
| 421 |
my @set_clauses = (); |
394 |
$sth->execute($shelfnumber); |
|
|
395 |
my $oldrecord= $sth->fetchrow_hashref; |
| 396 |
return 0 unless $oldrecord; #not found? |
| 422 |
|
397 |
|
| 423 |
foreach my $column (keys %$shelf) { |
398 |
#initialize missing hash values to silence warnings |
| 424 |
push @set_clauses, "$column = ?"; |
399 |
foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) { |
| 425 |
push @bind_params, $shelf->{$column}; |
400 |
$hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': ''; |
| 426 |
} |
401 |
} |
| 427 |
|
402 |
|
| 428 |
if ($#set_clauses == -1) { |
403 |
#if name or category changes, the name should be tested |
| 429 |
carp "No columns to update passed to ModShelf"; |
404 |
if($hashref->{shelfname} || $hashref->{category}) { |
| 430 |
return; |
405 |
unless(_CheckShelfName( |
|
|
406 |
$hashref->{shelfname}||$oldrecord->{shelfname}, |
| 407 |
$hashref->{category}||$oldrecord->{category}, |
| 408 |
$oldrecord->{owner}, $shelfnumber )) { |
| 409 |
return 0; #name check failed |
| 410 |
} |
| 431 |
} |
411 |
} |
| 432 |
$query .= join(", ", @set_clauses); |
|
|
| 433 |
|
| 434 |
$query .= " WHERE shelfnumber = ? "; |
| 435 |
push @bind_params, $shelfnumber; |
| 436 |
|
412 |
|
| 437 |
$debug and warn "ModShelf query:\n $query\n", |
413 |
#only the following fields from the hash may be changed |
| 438 |
"ModShelf query args: ", join(',', @bind_params), "\n"; |
414 |
$query= "UPDATE virtualshelves SET shelfname=?, category=?, sortfield=?, allow_add=?, allow_delete_own=?, allow_delete_other=? WHERE shelfnumber=?"; |
| 439 |
my $sth = $dbh->prepare($query); |
415 |
$sth = $dbh->prepare($query); |
| 440 |
$sth->execute( @bind_params ); |
416 |
$sth->execute( |
|
|
417 |
$hashref->{shelfname}||$oldrecord->{shelfname}, |
| 418 |
$hashref->{category}||$oldrecord->{category}, |
| 419 |
$hashref->{sortfield}||$oldrecord->{sortfield}, |
| 420 |
$hashref->{allow_add}||$oldrecord->{allow_add}, |
| 421 |
$hashref->{allow_delete_own}||$oldrecord->{allow_delete_own}, |
| 422 |
$hashref->{allow_delete_other}||$oldrecord->{allow_delete_other}, |
| 423 |
$shelfnumber ); |
| 424 |
return $@? 0: 1; |
| 441 |
} |
425 |
} |
| 442 |
|
426 |
|
| 443 |
=head2 ShelfPossibleAction |
427 |
=head2 ShelfPossibleAction |
|
Lines 446-452
ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
Link Here
|
| 446 |
|
430 |
|
| 447 |
C<$loggedinuser,$shelfnumber,$action> |
431 |
C<$loggedinuser,$shelfnumber,$action> |
| 448 |
|
432 |
|
| 449 |
$action can be "view" or "manage". |
433 |
$action can be "view", "add", "delete", "manage", "new_public", "new_private". |
|
|
434 |
Note that add/delete here refers to adding/deleting entries from the list. Deleting the list itself falls under manage. |
| 435 |
new_public and new_private refers to creating a new public or private list. |
| 436 |
The distinction between deleting your own entries from the list or entries from |
| 437 |
others is made in DelFromShelf. |
| 450 |
|
438 |
|
| 451 |
Returns 1 if the user can do the $action in the $shelfnumber shelf. |
439 |
Returns 1 if the user can do the $action in the $shelfnumber shelf. |
| 452 |
Returns 0 otherwise. |
440 |
Returns 0 otherwise. |
|
Lines 455-529
Returns 0 otherwise.
Link Here
|
| 455 |
|
443 |
|
| 456 |
sub ShelfPossibleAction { |
444 |
sub ShelfPossibleAction { |
| 457 |
my ( $user, $shelfnumber, $action ) = @_; |
445 |
my ( $user, $shelfnumber, $action ) = @_; |
| 458 |
my $query = qq( |
446 |
$action= 'view' unless $action; |
| 459 |
SELECT owner,category |
447 |
$user=0 unless $user; |
| 460 |
FROM virtualshelves |
448 |
|
| 461 |
WHERE shelfnumber=? |
449 |
if($action =~ /^new/) { #no shelfnumber needed |
| 462 |
); |
450 |
if($action eq 'new_private') { |
|
|
451 |
return $user>0; |
| 452 |
} |
| 453 |
elsif($action eq 'new_public') { |
| 454 |
return $user>0 && C4::Context->preference('OpacAllowPublicListCreation'); |
| 455 |
} |
| 456 |
return 0; |
| 457 |
} |
| 458 |
|
| 459 |
return 0 unless defined($shelfnumber); |
| 460 |
|
| 461 |
my $query = qq/ |
| 462 |
SELECT IFNULL(owner,0) AS owner, category, allow_add, allow_delete_own, allow_delete_other, IFNULL(sh.borrowernumber,0) AS borrowernumber |
| 463 |
FROM virtualshelves vs |
| 464 |
LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber |
| 465 |
AND sh.borrowernumber=? |
| 466 |
WHERE vs.shelfnumber=? |
| 467 |
/; |
| 463 |
my $sth = $dbh->prepare($query); |
468 |
my $sth = $dbh->prepare($query); |
| 464 |
$sth->execute($shelfnumber); |
469 |
$sth->execute($user, $shelfnumber); |
| 465 |
my ( $owner, $category ) = $sth->fetchrow; |
470 |
my $shelf= $sth->fetchrow_hashref; |
| 466 |
require C4::Members; |
471 |
|
| 467 |
my $borrower = C4::Members::GetMemberDetails($user); |
472 |
return 0 unless $shelf && ($shelf->{category}==2 || $shelf->{owner}==$user || $shelf->{borrowernumber}==$user); |
| 468 |
return 0 if not defined($user); |
473 |
if($action eq 'view') { |
| 469 |
return 1 if ( $category >= 3); # open list |
474 |
#already handled in the above condition |
| 470 |
return 1 if (($category >= 2) and |
475 |
return 1; |
| 471 |
defined($action) and $action eq 'view'); # public list, anybody can view |
476 |
} |
| 472 |
return 1 if (($category >= 2) and defined($user) and ($borrower->{authflags}->{superlibrarian} || $user == 0)); # public list, superlibrarian can edit/delete |
477 |
elsif($action eq 'add') { |
| 473 |
return 1 if (defined($user) and $owner eq $user ); # user owns this list. Check last. |
478 |
return 0 if $user<=0; #should be logged in |
|
|
479 |
return 1 if $shelf->{allow_add}==1 || $shelf->{owner}==$user; |
| 480 |
#owner may always add |
| 481 |
} |
| 482 |
elsif($action eq 'delete') { |
| 483 |
#this answer is just diplomatic: it says that you may be able to delete |
| 484 |
#some items from that shelf |
| 485 |
#it does not answer the question about a specific biblio |
| 486 |
#DelFromShelf checks the situation per biblio |
| 487 |
return 1 if $user>0 && ($shelf->{allow_delete_own}==1 || $shelf->{allow_delete_other}==1); |
| 488 |
} |
| 489 |
elsif($action eq 'manage') { |
| 490 |
return 1 if $user && $shelf->{owner}==$user; |
| 491 |
} |
| 474 |
return 0; |
492 |
return 0; |
| 475 |
} |
493 |
} |
| 476 |
|
494 |
|
| 477 |
=head2 DelFromShelf |
495 |
=head2 DelFromShelf |
| 478 |
|
496 |
|
| 479 |
&DelFromShelf( $biblionumber, $shelfnumber); |
497 |
$result= &DelFromShelf( $bibref, $shelfnumber, $user); |
| 480 |
|
498 |
|
| 481 |
Removes bib number C<$biblionumber> from virtual virtualshelves number |
499 |
Removes biblionumbers in passed arrayref from shelf C<$shelfnumber>. |
| 482 |
C<$shelfnumber>. If the bib wasn't on that virtualshelves to begin with, |
500 |
If the bib wasn't on that virtualshelves to begin with, nothing happens. |
| 483 |
nothing happens. |
501 |
|
|
|
502 |
Returns 0 if no items have been deleted. |
| 484 |
|
503 |
|
| 485 |
=cut |
504 |
=cut |
| 486 |
|
505 |
|
| 487 |
#' |
|
|
| 488 |
sub DelFromShelf { |
506 |
sub DelFromShelf { |
| 489 |
my ( $biblionumber, $shelfnumber ) = @_; |
507 |
my ($bibref, $shelfnumber, $user) = @_; |
| 490 |
my $query = qq( |
508 |
my $query = qq(SELECT allow_delete_own, allow_delete_other FROM virtualshelves WHERE shelfnumber=?); |
| 491 |
DELETE FROM virtualshelfcontents |
509 |
my $sth= $dbh->prepare($query); |
| 492 |
WHERE shelfnumber=? AND biblionumber=? |
510 |
$sth->execute($shelfnumber); |
| 493 |
); |
511 |
my ($del_own, $del_oth)= $sth->fetchrow; |
| 494 |
my $sth = $dbh->prepare($query); |
512 |
my $r; my $t=0; |
| 495 |
$sth->execute( $shelfnumber, $biblionumber ); |
513 |
|
|
|
514 |
if($del_own) { |
| 515 |
$query = qq(DELETE FROM virtualshelfcontents |
| 516 |
WHERE shelfnumber=? AND biblionumber=? AND borrowernumber=?); |
| 517 |
$sth= $dbh->prepare($query); |
| 518 |
foreach my $biblionumber (@$bibref) { |
| 519 |
$sth->execute($shelfnumber, $biblionumber, $user); |
| 520 |
$r= $sth->rows; #Expect -1, 0 or 1 (-1 means Don't know; count as 1) |
| 521 |
$t+= ($r==-1)? 1: $r; |
| 522 |
} |
| 523 |
} |
| 524 |
if($del_oth) { |
| 525 |
$query = qq(DELETE FROM virtualshelfcontents |
| 526 |
WHERE shelfnumber=? AND biblionumber=? AND borrowernumber<>?); |
| 527 |
$sth= $dbh->prepare($query); |
| 528 |
foreach my $biblionumber (@$bibref) { |
| 529 |
$sth->execute($shelfnumber, $biblionumber, $user); |
| 530 |
$r= $sth->rows; |
| 531 |
$t+= ($r==-1)? 1: $r; |
| 532 |
} |
| 533 |
} |
| 534 |
return $t; |
| 496 |
} |
535 |
} |
| 497 |
|
536 |
|
| 498 |
=head2 DelShelf (old version) |
537 |
=head2 DelShelf |
| 499 |
|
|
|
| 500 |
($status, $msg) = &DelShelf($shelfnumber); |
| 501 |
|
| 502 |
Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must |
| 503 |
be empty. |
| 504 |
|
| 505 |
Returns a two-element array, where C<$status> is 0 if the operation |
| 506 |
was successful, or non-zero otherwise. C<$msg> is "Done" in case of |
| 507 |
success, or an error message giving the reason for failure. |
| 508 |
|
| 509 |
=head2 DelShelf (current version) |
| 510 |
|
538 |
|
| 511 |
$Number = DelShelf($shelfnumber); |
539 |
$Number = DelShelf($shelfnumber); |
| 512 |
|
540 |
|
| 513 |
This function deletes the shelf number, and all of it's content. |
541 |
This function deletes the shelf number, and all of it's content. |
|
|
542 |
Authorization to do so MUST have been checked before calling, while using |
| 543 |
ShelfPossibleAction with manage parameter. |
| 514 |
|
544 |
|
| 515 |
=cut |
545 |
=cut |
| 516 |
|
546 |
|
| 517 |
sub DelShelf { |
547 |
sub DelShelf { |
| 518 |
unless (@_) { |
548 |
my ($shelfnumber)= @_; |
| 519 |
carp "DelShelf called without valid argument (shelfnumber)"; |
549 |
return unless $shelfnumber && $shelfnumber =~ /^\d+$/; |
| 520 |
return undef; |
550 |
my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?"); |
| 521 |
} |
551 |
return $sth->execute($shelfnumber); |
| 522 |
my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?"); |
|
|
| 523 |
return $sth->execute(shift); |
| 524 |
} |
552 |
} |
| 525 |
|
553 |
|
| 526 |
=head2 GetBibShelves |
554 |
=head2 GetBibliosShelves |
| 527 |
|
555 |
|
| 528 |
This finds all the public lists that this bib record is in. |
556 |
This finds all the public lists that this bib record is in. |
| 529 |
|
557 |
|
|
Lines 536-600
sub GetBibliosShelves {
Link Here
|
| 536 |
SELECT vs.shelfname, vs.shelfnumber |
564 |
SELECT vs.shelfname, vs.shelfnumber |
| 537 |
FROM virtualshelves vs |
565 |
FROM virtualshelves vs |
| 538 |
JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber) |
566 |
JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber) |
| 539 |
WHERE vs.category != 1 |
567 |
WHERE vs.category=2 |
| 540 |
AND vc.biblionumber= ? |
568 |
AND vc.biblionumber= ? |
| 541 |
'); |
569 |
'); |
| 542 |
$sth->execute( $biblionumber ); |
570 |
$sth->execute( $biblionumber ); |
| 543 |
return $sth->fetchall_arrayref({}); |
571 |
return $sth->fetchall_arrayref({}); |
| 544 |
} |
572 |
} |
| 545 |
|
573 |
|
| 546 |
=head2 RefreshShelvesSummary |
574 |
=head2 ShelvesMax |
| 547 |
|
575 |
|
| 548 |
($total, $pubshelves, $barshelves) = RefreshShelvesSummary($sessionID, $loggedinuser, $row_count); |
576 |
$howmany= ShelvesMax($context); |
| 549 |
|
577 |
|
| 550 |
Updates the current session and userenv with the most recent shelves |
578 |
Tells how much shelves are shown in which context. |
| 551 |
|
579 |
POPUP refers to addbybiblionumber popup, MGRPAGE is managing page (in opac or |
| 552 |
Returns the total number of shelves stored in the session/userenv along with two references each to an |
580 |
staff), COMBO refers to the Add to-combo of search results. MASTHEAD is the |
| 553 |
array of hashes, one containing the C<$loggedinuser>'s private shelves and one containing all public/open shelves. |
581 |
main Koha toolbar with Lists button. |
| 554 |
|
|
|
| 555 |
This function is used in conjunction with the 'Lists' button in masthead.inc. |
| 556 |
|
582 |
|
| 557 |
=cut |
583 |
=cut |
| 558 |
|
584 |
|
| 559 |
sub RefreshShelvesSummary ($$$) { |
585 |
sub ShelvesMax { |
| 560 |
require C4::Auth; |
586 |
my $which= shift; |
| 561 |
my ($sessionID, $loggedinuser, $row_count) = @_; |
587 |
return SHELVES_POPUP_MAX if $which eq 'POPUP'; |
| 562 |
my $session = C4::Auth::get_session($sessionID); |
588 |
return SHELVES_MGRPAGE_MAX if $which eq 'MGRPAGE'; |
| 563 |
my ($total, $totshelves, $barshelves, $pubshelves); |
589 |
return SHELVES_COMBO_MAX if $which eq 'COMBO'; |
| 564 |
|
590 |
return SHELVES_MASTHEAD_MAX if $which eq 'MASTHEAD'; |
| 565 |
($barshelves, $totshelves) = GetRecentShelves(1, $row_count, $loggedinuser); |
591 |
return SHELVES_MASTHEAD_MAX; |
| 566 |
$total->{'bartotal'} = $totshelves; |
|
|
| 567 |
($pubshelves, $totshelves) = GetRecentShelves(2, $row_count, undef); |
| 568 |
$total->{'pubtotal'} = $totshelves; |
| 569 |
|
| 570 |
# Update the current session with the latest shelves... |
| 571 |
$session->param('barshelves', $barshelves); |
| 572 |
$session->param('pubshelves', $pubshelves); |
| 573 |
$session->param('totshelves', $total); |
| 574 |
|
| 575 |
# likewise the userenv... |
| 576 |
C4::Context->set_shelves_userenv('bar',$barshelves); |
| 577 |
C4::Context->set_shelves_userenv('pub',$pubshelves); |
| 578 |
C4::Context::set_shelves_userenv('tot',$total); |
| 579 |
|
| 580 |
return ($total, $pubshelves, $barshelves); |
| 581 |
} |
592 |
} |
| 582 |
|
593 |
|
| 583 |
# internal subs |
594 |
# internal subs |
| 584 |
|
595 |
|
| 585 |
sub _shelf_count ($$) { |
596 |
sub _shelf_count { |
| 586 |
my (@params) = @_; |
597 |
my ($owner, $category) = @_; |
| 587 |
# Find out how many shelves total meet the submitted criteria... |
598 |
my @params; |
| 588 |
my $query = "SELECT count(*) FROM virtualshelves"; |
599 |
# Find out how many shelves total meet the submitted criteria... |
| 589 |
$query .= ($params[1] > 1) ? " WHERE category >= ?" : " WHERE owner=? AND category=?"; |
600 |
|
| 590 |
shift @params if $params[1] > 1; |
601 |
my $query = "SELECT count(*) FROM virtualshelves vs "; |
| 591 |
my $sth = $dbh->prepare($query); |
602 |
if($category==1) { |
| 592 |
$sth->execute(@params); |
603 |
$query.= qq{ |
| 593 |
my $total = $sth->fetchrow; |
604 |
LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber |
| 594 |
return $total; |
605 |
AND sh.borrowernumber=? |
|
|
606 |
WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) }; |
| 607 |
@params= ($owner, $owner, $owner); |
| 608 |
} |
| 609 |
else { |
| 610 |
$query.='WHERE category=2'; |
| 611 |
@params= (); |
| 612 |
} |
| 613 |
my $sth = $dbh->prepare($query); |
| 614 |
$sth->execute(@params); |
| 615 |
my ($total)= $sth->fetchrow; |
| 616 |
return $total; |
| 595 |
} |
617 |
} |
| 596 |
|
618 |
|
| 597 |
sub _biblionumber_sth { |
619 |
sub _biblionumber_sth { #only used in obsolete sub below |
| 598 |
my ($shelf) = @_; |
620 |
my ($shelf) = @_; |
| 599 |
my $query = 'select biblionumber from virtualshelfcontents where shelfnumber = ?'; |
621 |
my $query = 'select biblionumber from virtualshelfcontents where shelfnumber = ?'; |
| 600 |
my $dbh = C4::Context->dbh; |
622 |
my $dbh = C4::Context->dbh; |
|
Lines 605-611
sub _biblionumber_sth {
Link Here
|
| 605 |
$sth; |
627 |
$sth; |
| 606 |
} |
628 |
} |
| 607 |
|
629 |
|
| 608 |
sub each_biblionumbers (&$) { |
630 |
sub each_biblionumbers (&$) { #OBSOLETE |
| 609 |
my ($code,$shelf) = @_; |
631 |
my ($code,$shelf) = @_; |
| 610 |
my $ref = _biblionumber_sth($shelf)->fetchall_arrayref; |
632 |
my $ref = _biblionumber_sth($shelf)->fetchall_arrayref; |
| 611 |
map { |
633 |
map { |
|
Lines 614-619
sub each_biblionumbers (&$) {
Link Here
|
| 614 |
} @$ref; |
636 |
} @$ref; |
| 615 |
} |
637 |
} |
| 616 |
|
638 |
|
|
|
639 |
sub _CheckShelfName { |
| 640 |
my ($name, $cat, $owner, $number)= @_; |
| 641 |
|
| 642 |
my $query = qq( |
| 643 |
SELECT DISTINCT shelfnumber |
| 644 |
FROM virtualshelves |
| 645 |
LEFT JOIN virtualshelfshares sh USING (shelfnumber) |
| 646 |
WHERE shelfname=? AND shelfnumber<>?); |
| 647 |
if($cat==1) { |
| 648 |
$query.= ' AND (sh.borrowernumber=? OR owner=?) AND category=1'; |
| 649 |
} |
| 650 |
else { |
| 651 |
$query.= ' AND category=2'; |
| 652 |
} |
| 653 |
my $sth = $dbh->prepare($query); |
| 654 |
$sth->execute($cat==1? ($name, $number, $owner, $owner): ($name, $number)); |
| 655 |
return $sth->rows>0? 0: 1; |
| 656 |
} |
| 657 |
|
| 617 |
1; |
658 |
1; |
| 618 |
|
659 |
|
| 619 |
__END__ |
660 |
__END__ |