Filename | /mnt/catalyst/koha/C4/ItemCirculationAlertPreference.pm |
Statements | Executed 15 statements in 5.91ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.52ms | 3.01ms | BEGIN@24 | C4::ItemCirculationAlertPreference::
1 | 1 | 1 | 2.13ms | 2.61ms | BEGIN@23 | C4::ItemCirculationAlertPreference::
1 | 1 | 1 | 452µs | 468µs | BEGIN@20 | C4::ItemCirculationAlertPreference::
1 | 1 | 1 | 10µs | 40µs | BEGIN@25 | C4::ItemCirculationAlertPreference::
1 | 1 | 1 | 10µs | 18µs | BEGIN@21 | C4::ItemCirculationAlertPreference::
1 | 1 | 1 | 10µs | 12µs | BEGIN@22 | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | AUTOLOAD | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | DESTROY | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | __ANON__[:35] | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | create | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | delete | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | find | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | grid | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | is_disabled_for | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | is_enabled_for | C4::ItemCirculationAlertPreference::
0 | 0 | 0 | 0s | 0s | new | C4::ItemCirculationAlertPreference::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package C4::ItemCirculationAlertPreference; | ||||
2 | |||||
3 | # Copyright Liblime 2009 | ||||
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 | |||||
20 | 2 | 31µs | 2 | 483µs | # spent 468µs (452+16) within C4::ItemCirculationAlertPreference::BEGIN@20 which was called:
# once (452µs+16µs) by C4::Circulation::BEGIN@34 at line 20 # spent 468µs making 1 call to C4::ItemCirculationAlertPreference::BEGIN@20
# spent 16µs making 1 call to strict::import |
21 | 2 | 22µs | 2 | 26µs | # spent 18µs (10+8) within C4::ItemCirculationAlertPreference::BEGIN@21 which was called:
# once (10µs+8µs) by C4::Circulation::BEGIN@34 at line 21 # spent 18µs making 1 call to C4::ItemCirculationAlertPreference::BEGIN@21
# spent 8µs making 1 call to warnings::import |
22 | 2 | 147µs | 2 | 14µs | # spent 12µs (10+2) within C4::ItemCirculationAlertPreference::BEGIN@22 which was called:
# once (10µs+2µs) by C4::Circulation::BEGIN@34 at line 22 # spent 12µs making 1 call to C4::ItemCirculationAlertPreference::BEGIN@22
# spent 2µs making 1 call to C4::Context::import |
23 | 2 | 2.21ms | 1 | 2.61ms | # spent 2.61ms (2.13+481µs) within C4::ItemCirculationAlertPreference::BEGIN@23 which was called:
# once (2.13ms+481µs) by C4::Circulation::BEGIN@34 at line 23 # spent 2.61ms making 1 call to C4::ItemCirculationAlertPreference::BEGIN@23 |
24 | 2 | 2.54ms | 1 | 3.01ms | # spent 3.01ms (2.52+497µs) within C4::ItemCirculationAlertPreference::BEGIN@24 which was called:
# once (2.52ms+497µs) by C4::Circulation::BEGIN@34 at line 24 # spent 3.01ms making 1 call to C4::ItemCirculationAlertPreference::BEGIN@24 |
25 | 2 | 961µs | 2 | 70µs | # spent 40µs (10+30) within C4::ItemCirculationAlertPreference::BEGIN@25 which was called:
# once (10µs+30µs) by C4::Circulation::BEGIN@34 at line 25 # spent 40µs making 1 call to C4::ItemCirculationAlertPreference::BEGIN@25
# spent 30µs making 1 call to Exporter::import |
26 | |||||
27 | 1 | 100ns | our $AUTOLOAD; | ||
28 | |||||
29 | # helper function for validating \%opts | ||||
30 | our $valid = sub { | ||||
31 | my $opts = shift; | ||||
32 | for (qw(branchcode categorycode item_type notification)) { | ||||
33 | exists($opts->{$_}) || croak("'$_' is a required parameter."); | ||||
34 | } | ||||
35 | 1 | 3µs | }; | ||
36 | |||||
- - | |||||
40 | =head1 NAME | ||||
41 | |||||
42 | C4::ItemCirculationAlertPreference - manage preferences for sending alerts | ||||
43 | |||||
44 | =head1 SYNOPSIS | ||||
45 | |||||
46 | Basics: | ||||
47 | |||||
48 | use C4::ItemCirculationAlertPreference; | ||||
49 | |||||
50 | # a short-cut to reduce typing the long package name over and over again | ||||
51 | my $preferences = 'C4::ItemCirculationAlertPreference'; | ||||
52 | |||||
53 | Creating a restriction on sending messages: | ||||
54 | |||||
55 | my $pref = $preferences->create({ | ||||
56 | branchcode => 'CPL', | ||||
57 | categorycode => 'YA', | ||||
58 | item_type => 'BK', | ||||
59 | notification => 'CHECKOUT', | ||||
60 | }); | ||||
61 | |||||
62 | Removing a restriction on sending messages: | ||||
63 | |||||
64 | $preferences->delete({ | ||||
65 | branchcode => 'CPL', | ||||
66 | categorycode => 'YA', | ||||
67 | item_type => 'BK', | ||||
68 | notification => 'CHECKOUT', | ||||
69 | }); | ||||
70 | |||||
71 | =head1 DESCRIPTION | ||||
72 | |||||
73 | This class is used to manage the preferences for when an alert may be sent. By | ||||
74 | default, item circulation alerts are enabled for every B<branch>, B<patron | ||||
75 | category> and B<item type>. | ||||
76 | |||||
77 | However, if you would like to prevent item circulation alerts from being sent | ||||
78 | for any combination of these 3 variables, a preference can be inserted into the | ||||
79 | C<item_circulation_alert_preferences> table to make that a policy. | ||||
80 | |||||
81 | =head1 API | ||||
82 | |||||
83 | =head2 Class Methods | ||||
84 | |||||
85 | =cut | ||||
86 | |||||
87 | =head3 C4::ItemCirculationAlertPreference->new(\%opts) | ||||
88 | |||||
89 | This is a constructor for an in-memory C4::ItemCirculationAlertPreference | ||||
90 | object. The database is not affected by this method. | ||||
91 | |||||
92 | =cut | ||||
93 | |||||
94 | sub new { | ||||
95 | my ($class, $opts) = @_; | ||||
96 | bless $opts => $class; | ||||
97 | } | ||||
98 | |||||
- - | |||||
102 | =head3 C4::ItemCirculationAlertPreference->create(\%opts) | ||||
103 | |||||
104 | This will find or create an item circulation alert preference. You must pass | ||||
105 | it a B<branchcode>, B<categorycode>, B<item_type>, and B<notification>. Valid | ||||
106 | values for these attributes are as follows: | ||||
107 | |||||
108 | =over 4 | ||||
109 | |||||
110 | =item branchcode | ||||
111 | |||||
112 | branches.branchcode | ||||
113 | |||||
114 | =item categorycode | ||||
115 | |||||
116 | category.categorycode | ||||
117 | |||||
118 | =item item_type | ||||
119 | |||||
120 | itemtypes.itemtype | ||||
121 | |||||
122 | =item notification | ||||
123 | |||||
124 | This can be "CHECKIN" or "CHECKOUT" | ||||
125 | |||||
126 | =back | ||||
127 | |||||
128 | =cut | ||||
129 | |||||
130 | sub create { | ||||
131 | my ($class, $opts) = @_; | ||||
132 | $valid->($opts); | ||||
133 | my $dbh = C4::Context->dbh; | ||||
134 | my $prefs = $dbh->selectall_arrayref( | ||||
135 | "SELECT id, branchcode, categorycode, item_type | ||||
136 | FROM item_circulation_alert_preferences | ||||
137 | WHERE branchcode = ? | ||||
138 | AND categorycode = ? | ||||
139 | AND item_type = ? | ||||
140 | AND notification = ?", | ||||
141 | { Slice => {} }, | ||||
142 | $opts->{branchcode}, | ||||
143 | $opts->{categorycode}, | ||||
144 | $opts->{item_type}, | ||||
145 | $opts->{notification}, | ||||
146 | ); | ||||
147 | if (@$prefs) { | ||||
148 | return $class->new($prefs->[0]); | ||||
149 | } else { | ||||
150 | my $success = $dbh->do( | ||||
151 | "INSERT INTO item_circulation_alert_preferences | ||||
152 | (branchcode, categorycode, item_type, notification) VALUES (?, ?, ?, ?)", | ||||
153 | {}, | ||||
154 | $opts->{branchcode}, | ||||
155 | $opts->{categorycode}, | ||||
156 | $opts->{item_type}, | ||||
157 | $opts->{notification}, | ||||
158 | ); | ||||
159 | if ($success) { | ||||
160 | my $self = { | ||||
161 | id => $dbh->last_insert_id(undef, undef, undef, undef), | ||||
162 | branchcode => $opts->{branchcode}, | ||||
163 | categorycode => $opts->{categorycode}, | ||||
164 | item_type => $opts->{item_type}, | ||||
165 | notification => $opts->{notification}, | ||||
166 | }; | ||||
167 | return $class->new($self); | ||||
168 | } else { | ||||
169 | carp $dbh->errstr; | ||||
170 | return; | ||||
171 | } | ||||
172 | } | ||||
173 | } | ||||
174 | |||||
- - | |||||
178 | =head3 C4::ItemCirculationAlertPreference->delete(\%opts) | ||||
179 | |||||
180 | Delete an item circulation alert preference. You can delete by either passing | ||||
181 | in an B<id> or passing in a B<branchcode>, B<categorycode>, B<item_type> | ||||
182 | triplet. | ||||
183 | |||||
184 | =cut | ||||
185 | |||||
186 | sub delete { | ||||
187 | my ($class, $opts) = @_; | ||||
188 | my $dbh = C4::Context->dbh; | ||||
189 | if ($opts->{id}) { | ||||
190 | $dbh->do( | ||||
191 | "DELETE FROM item_circulation_alert_preferences WHERE id = ?", | ||||
192 | {}, | ||||
193 | $opts->{id} | ||||
194 | ); | ||||
195 | } else { | ||||
196 | $valid->($opts); | ||||
197 | my $sql = | ||||
198 | "DELETE FROM item_circulation_alert_preferences | ||||
199 | WHERE branchcode = ? | ||||
200 | AND categorycode = ? | ||||
201 | AND item_type = ? | ||||
202 | AND notification = ?"; | ||||
203 | $dbh->do( | ||||
204 | $sql, | ||||
205 | {}, | ||||
206 | $opts->{branchcode}, | ||||
207 | $opts->{categorycode}, | ||||
208 | $opts->{item_type}, | ||||
209 | $opts->{notification}, | ||||
210 | ); | ||||
211 | } | ||||
212 | } | ||||
213 | |||||
- - | |||||
217 | =head3 C4::ItemCirculationAlertPreference->is_enabled_for(\%opts) | ||||
218 | |||||
219 | Based on the existing preferences in the C<item_circulation_alert_preferences> | ||||
220 | table, can an alert be sent for the given B<branchcode>, B<categorycode>, and | ||||
221 | B<itemtype>? | ||||
222 | |||||
223 | B<Example>: | ||||
224 | |||||
225 | my $alert = 'C4::ItemCirculationAlertPreference'; | ||||
226 | my $conditions = { | ||||
227 | branchcode => 'CPL', | ||||
228 | categorycode => 'IL', | ||||
229 | item_type => 'MU', | ||||
230 | }; | ||||
231 | |||||
232 | if ($alert->is_enabled_for($conditions)) { | ||||
233 | # ... | ||||
234 | } | ||||
235 | |||||
236 | =cut | ||||
237 | |||||
238 | sub is_disabled_for { | ||||
239 | my ($class, $opts) = @_; | ||||
240 | $valid->($opts); | ||||
241 | my $dbh = C4::Context->dbh; | ||||
242 | |||||
243 | # Does a preference exist to block this alert? | ||||
244 | my $query = qq{ | ||||
245 | SELECT id, branchcode, categorycode, item_type, notification | ||||
246 | FROM item_circulation_alert_preferences | ||||
247 | WHERE (branchcode = ? OR branchcode = '*') | ||||
248 | AND (categorycode = ? OR categorycode = '*') | ||||
249 | AND (item_type = ? OR item_type = '*') | ||||
250 | AND (notification = ? OR notification = '*') | ||||
251 | }; | ||||
252 | |||||
253 | my $preferences = $dbh->selectall_arrayref( | ||||
254 | $query, | ||||
255 | { Slice => {} }, | ||||
256 | $opts->{branchcode}, | ||||
257 | $opts->{categorycode}, | ||||
258 | $opts->{item_type}, | ||||
259 | $opts->{notification}, | ||||
260 | ); | ||||
261 | |||||
262 | # If any preferences showed up, we are NOT enabled. | ||||
263 | return @$preferences; | ||||
264 | } | ||||
265 | |||||
266 | sub is_enabled_for { | ||||
267 | my ($class, $opts) = @_; | ||||
268 | return not $class->is_disabled_for($opts); | ||||
269 | } | ||||
270 | |||||
- - | |||||
274 | =head3 C4::ItemCirculationAlertPreference->find({ branchcode => $bc, notification => $type }) | ||||
275 | |||||
276 | This method returns all the item circulation alert preferences for a given | ||||
277 | branch and notification. | ||||
278 | |||||
279 | B<Example>: | ||||
280 | |||||
281 | my @branch_prefs = C4::ItemCirculationAlertPreference->find({ | ||||
282 | branchcode => 'CPL', | ||||
283 | notification => 'CHECKIN', | ||||
284 | }); | ||||
285 | |||||
286 | =cut | ||||
287 | |||||
288 | sub find { | ||||
289 | my ($class, $where) = @_; | ||||
290 | my $dbh = C4::Context->dbh; | ||||
291 | my $query = qq{ | ||||
292 | SELECT id, branchcode, categorycode, item_type, notification | ||||
293 | FROM item_circulation_alert_preferences | ||||
294 | WHERE branchcode = ? AND notification = ? | ||||
295 | ORDER BY categorycode, item_type | ||||
296 | }; | ||||
297 | return map { $class->new($_) } @{$dbh->selectall_arrayref( | ||||
298 | $query, | ||||
299 | { Slice => {} }, | ||||
300 | $where->{branchcode}, | ||||
301 | $where->{notification}, | ||||
302 | )}; | ||||
303 | } | ||||
304 | |||||
- - | |||||
308 | =head3 C4::ItemCirculationAlertPreference->grid({ branchcode => $c, notification => $type }) | ||||
309 | |||||
310 | Return a 2D arrayref for the grid view in F<admin/item_circulation_alert_preferences.pl>. | ||||
311 | Each row represents a category (like 'Patron' or 'Young Adult') and | ||||
312 | each column represents an itemtype (like 'Book' or 'Music'). | ||||
313 | |||||
314 | Each cell contains... | ||||
315 | |||||
316 | B<Example>: | ||||
317 | |||||
318 | use Data::Dump 'pp'; | ||||
319 | my $grid = C4::ItemCirculationAlertPreference->grid({ | ||||
320 | branchcode => 'CPL', | ||||
321 | notification => 'CHECKOUT', | ||||
322 | }); | ||||
323 | warn pp($grid); | ||||
324 | |||||
325 | See F<admin/item_circulation_alerts.pl> to see how this method is used. | ||||
326 | |||||
327 | =cut | ||||
328 | |||||
329 | sub grid { | ||||
330 | my ($class, $where) = @_; | ||||
331 | my @branch_prefs = $class->find($where); | ||||
332 | my @default_prefs = $class->find({ branchcode => '*', notification => $where->{notification} }); | ||||
333 | my @cc = C4::Category->all; | ||||
334 | my @it = C4::ItemType->all; | ||||
335 | my $notification = $where->{notification}; | ||||
336 | my %disabled = map { | ||||
337 | my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification; | ||||
338 | $key =~ s/\*/_/g; | ||||
339 | ($key => 1); | ||||
340 | } @branch_prefs; | ||||
341 | my %default = map { | ||||
342 | my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification; | ||||
343 | $key =~ s/\*/_/g; | ||||
344 | ($key => 1); | ||||
345 | } @default_prefs; | ||||
346 | my @grid; | ||||
347 | for my $c (@cc) { | ||||
348 | my $row = { description => $c->description, items => [] }; | ||||
349 | push @grid, $row; | ||||
350 | for my $i (@it) { | ||||
351 | my $key = $c->categorycode . "-" . $i->itemtype . "-" . $notification; | ||||
352 | $key =~ s/\*/_/g; | ||||
353 | my @classes; | ||||
354 | my $text = " "; | ||||
355 | if ($disabled{$key}) { | ||||
356 | push @classes, 'disabled'; | ||||
357 | $text = "Disabled for $where->{branchcode}"; | ||||
358 | } | ||||
359 | if ($default{$key}) { | ||||
360 | push @classes, 'default'; | ||||
361 | $text = "Disabled for all"; | ||||
362 | } | ||||
363 | push @{$row->{items}}, { | ||||
364 | class => join(' ', @classes), | ||||
365 | id => $key, | ||||
366 | text => $text, | ||||
367 | }; | ||||
368 | } | ||||
369 | } | ||||
370 | return \@grid; | ||||
371 | } | ||||
372 | |||||
- - | |||||
376 | =head2 Object Methods | ||||
377 | |||||
378 | These are read-only accessors for the various attributes of a preference. | ||||
379 | |||||
380 | =head3 $pref->id | ||||
381 | |||||
382 | =cut | ||||
383 | |||||
384 | =head3 $pref->branchcode | ||||
385 | |||||
386 | =cut | ||||
387 | |||||
388 | =head3 $pref->categorycode | ||||
389 | |||||
390 | =cut | ||||
391 | |||||
392 | =head3 $pref->item_type | ||||
393 | |||||
394 | =cut | ||||
395 | |||||
396 | =head3 $pref->notification | ||||
397 | |||||
398 | =cut | ||||
399 | |||||
400 | sub AUTOLOAD { | ||||
401 | my $self = shift; | ||||
402 | my $attr = $AUTOLOAD; | ||||
403 | $attr =~ s/.*://; | ||||
404 | if (exists $self->{$attr}) { | ||||
405 | return $self->{$attr}; | ||||
406 | } else { | ||||
407 | return; | ||||
408 | } | ||||
409 | } | ||||
410 | |||||
411 | sub DESTROY { } | ||||
412 | |||||
- - | |||||
415 | =head1 SEE ALSO | ||||
416 | |||||
417 | L<C4::Circulation>, F<admin/item_circulation_alerts.pl> | ||||
418 | |||||
419 | =head1 AUTHOR | ||||
420 | |||||
421 | John Beppu <john.beppu@liblime.com> | ||||
422 | |||||
423 | =cut | ||||
424 | |||||
425 | 1 | 3µs | 1; |