replace references to defunct info email address
[koha.git] / C4 / Members / AttributeTypes.pm
1 package C4::Members::AttributeTypes;
2
3 # Copyright (C) 2008 LibLime
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 use strict;
21 #use warnings; FIXME - Bug 2505
22 use C4::Context;
23
24 use vars qw($VERSION);
25
26 BEGIN {
27     # set the version for version checking
28     $VERSION = 3.00;
29 }
30
31 =head1 NAME
32
33 C4::Members::AttributeTypes - mananage extended patron attribute types
34
35 =head1 SYNOPSIS
36
37 =over 4
38
39 my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes();
40
41 my $attr_type = C4::Members::AttributeTypes->new($code, $description);
42 $attr_type->code($code);
43 $attr_type->description($description);
44 $attr_type->repeatable($repeatable);
45 $attr_type->unique_id($unique_id);
46 $attr_type->opac_display($opac_display);
47 $attr_type->password_allowed($password_allowed);
48 $attr_type->staff_searchable($staff_searchable);
49 $attr_type->authorised_value_category($authorised_value_category);
50 $attr_type->store();
51 $attr_type->delete();
52
53 my $attr_type = C4::Members::AttributeTypes->fetch($code);
54 $attr_type = C4::Members::AttributeTypes->delete($code);
55
56 =back
57
58 =head1 FUNCTIONS
59
60 =head2 GetAttributeTypes
61
62 =over 4
63
64 my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes($all_fields);
65
66 =back
67
68 Returns an array of hashrefs of each attribute type defined
69 in the database.  The array is sorted by code.  Each hashref contains
70 at least the following fields:
71
72 code
73 description
74
75 If $all_fields is true, then each hashref also contains the other fields from borrower_attribute_types.
76
77 =cut
78
79 sub GetAttributeTypes {
80     my $all = @_ ? shift : 0;
81     my $select = $all ? '*' : 'code, description';
82     my $dbh = C4::Context->dbh;
83     my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code");
84     $sth->execute();
85     my $results = $sth->fetchall_arrayref({});
86     return @$results;
87 }
88
89 sub GetAttributeTypes_hashref {
90     my %hash = map {$_->{code} => $_} GetAttributeTypes(@_);
91     return \%hash;
92 }
93
94 =head1 METHODS 
95
96 =over 4
97
98 my $attr_type = C4::Members::AttributeTypes->new($code, $description);
99
100 =back
101
102 Create a new attribute type.
103
104 =cut 
105
106 sub new {
107     my $class = shift;
108     my $self = {};
109
110     $self->{'code'} = shift;
111     $self->{'description'} = shift;
112     $self->{'repeatable'} = 0;
113     $self->{'unique_id'} = 0;
114     $self->{'opac_display'} = 0;
115     $self->{'password_allowed'} = 0;
116     $self->{'staff_searchable'} = 0;
117     $self->{'authorised_value_category'} = '';
118
119     bless $self, $class;
120     return $self;
121 }
122
123 =head2 fetch
124
125 =over 4
126
127 my $attr_type = C4::Members::AttributeTypes->fetch($code);
128
129 =back
130
131 Fetches an attribute type from the database.  If no
132 type with the given C<$code> exists, returns undef.
133
134 =cut
135
136 sub fetch {
137     my $class = shift;
138     my $code = shift;
139     my $self = {};
140     my $dbh = C4::Context->dbh();
141
142     my $sth = $dbh->prepare_cached("SELECT * FROM borrower_attribute_types WHERE code = ?");
143     $sth->execute($code);
144     my $row = $sth->fetchrow_hashref;
145     $sth->finish();
146     return undef unless defined $row;    
147
148     $self->{'code'}                      = $row->{'code'};
149     $self->{'description'}               = $row->{'description'};
150     $self->{'repeatable'}                = $row->{'repeatable'};
151     $self->{'unique_id'}                 = $row->{'unique_id'};
152     $self->{'opac_display'}              = $row->{'opac_display'};
153     $self->{'password_allowed'}          = $row->{'password_allowed'};
154     $self->{'staff_searchable'}          = $row->{'staff_searchable'};
155     $self->{'authorised_value_category'} = $row->{'authorised_value_category'};
156
157     bless $self, $class;
158     return $self;
159 }
160
161 =head2 store
162
163 =over 4
164
165 $attr_type->store();
166
167 =back
168
169 Stores attribute type in the database.  If the type
170 previously retrieved from the database via the fetch()
171 method, the DB representation of the type is replaced.
172
173 =cut
174
175 sub store {
176     my $self = shift;
177
178     my $dbh = C4::Context->dbh;
179     my $sth;
180     my $existing = __PACKAGE__->fetch($self->{'code'});
181     if (defined $existing) {
182         $sth = $dbh->prepare_cached("UPDATE borrower_attribute_types
183                                      SET description = ?,
184                                          repeatable = ?,
185                                          unique_id = ?,
186                                          opac_display = ?,
187                                          password_allowed = ?,
188                                          staff_searchable = ?,
189                                          authorised_value_category = ?
190                                      WHERE code = ?");
191     } else {
192         $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types 
193                                         (description, repeatable, unique_id, opac_display, password_allowed,
194                                          staff_searchable, authorised_value_category, code)
195                                         VALUES (?, ?, ?, ?, ?,
196                                                 ?, ?, ?)");
197     }
198     $sth->bind_param(1, $self->{'description'});
199     $sth->bind_param(2, $self->{'repeatable'});
200     $sth->bind_param(3, $self->{'unique_id'});
201     $sth->bind_param(4, $self->{'opac_display'});
202     $sth->bind_param(5, $self->{'password_allowed'});
203     $sth->bind_param(6, $self->{'staff_searchable'});
204     $sth->bind_param(7, $self->{'authorised_value_category'});
205     $sth->bind_param(8, $self->{'code'});
206     $sth->execute;
207
208 }
209
210 =head2 code
211
212 =over 4
213
214 my $code = $attr_type->code();
215 $attr_type->code($code);
216
217 =back
218
219 Accessor.  Note that the code is immutable once
220 a type is created or fetched from the database.
221
222 =cut
223
224 sub code {
225     my $self = shift;
226     return $self->{'code'};
227 }
228
229 =head2 description
230
231 =over 4
232
233 my $description = $attr_type->description();
234 $attr_type->description($description);
235
236 =back
237
238 Accessor.
239
240 =cut
241
242 sub description {
243     my $self = shift;
244     @_ ? $self->{'description'} = shift : $self->{'description'};
245 }
246
247 =head2 repeatable
248
249 =over 4
250
251 my $repeatable = $attr_type->repeatable();
252 $attr_type->repeatable($repeatable);
253
254 =back
255
256 Accessor.  The C<$repeatable> argument
257 is interpreted as a Perl boolean.
258
259 =cut
260
261 sub repeatable {
262     my $self = shift;
263     @_ ? $self->{'repeatable'} = ((shift) ? 1 : 0) : $self->{'repeatable'};
264 }
265
266 =head2 unique_id
267
268 =over 4
269
270 my $unique_id = $attr_type->unique_id();
271 $attr_type->unique_id($unique_id);
272
273 =back
274
275 Accessor.  The C<$unique_id> argument
276 is interpreted as a Perl boolean.
277
278 =cut
279
280 sub unique_id {
281     my $self = shift;
282     @_ ? $self->{'unique_id'} = ((shift) ? 1 : 0) : $self->{'unique_id'};
283 }
284 =head2 opac_display
285
286 =over 4
287
288 my $opac_display = $attr_type->opac_display();
289 $attr_type->opac_display($opac_display);
290
291 =back
292
293 Accessor.  The C<$opac_display> argument
294 is interpreted as a Perl boolean.
295
296 =cut
297
298 sub opac_display {
299     my $self = shift;
300     @_ ? $self->{'opac_display'} = ((shift) ? 1 : 0) : $self->{'opac_display'};
301 }
302 =head2 password_allowed
303
304 =over 4
305
306 my $password_allowed = $attr_type->password_allowed();
307 $attr_type->password_allowed($password_allowed);
308
309 =back
310
311 Accessor.  The C<$password_allowed> argument
312 is interpreted as a Perl boolean.
313
314 =cut
315
316 sub password_allowed {
317     my $self = shift;
318     @_ ? $self->{'password_allowed'} = ((shift) ? 1 : 0) : $self->{'password_allowed'};
319 }
320 =head2 staff_searchable
321
322 =over 4
323
324 my $staff_searchable = $attr_type->staff_searchable();
325 $attr_type->staff_searchable($staff_searchable);
326
327 =back
328
329 Accessor.  The C<$staff_searchable> argument
330 is interpreted as a Perl boolean.
331
332 =cut
333
334 sub staff_searchable {
335     my $self = shift;
336     @_ ? $self->{'staff_searchable'} = ((shift) ? 1 : 0) : $self->{'staff_searchable'};
337 }
338
339 =head2 authorised_value_category
340
341 =over 4
342
343 my $authorised_value_category = $attr_type->authorised_value_category();
344 $attr_type->authorised_value_category($authorised_value_category);
345
346 =back
347
348 Accessor.
349
350 =cut
351
352 sub authorised_value_category {
353     my $self = shift;
354     @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'};
355 }
356
357 =head2 delete
358
359 =over 4
360
361 $attr_type->delete();
362 C4::Members::AttributeTypes->delete($code);
363
364 =back
365
366 Delete an attribute type from the database.  The attribute
367 type may be specified either by an object or by a code.
368
369 =cut
370
371 sub delete {
372     my $arg = shift;
373     my $code;
374     if (ref($arg) eq __PACKAGE__) {
375         $code = $arg->{'code'};
376     } else {
377         $code = shift;
378     }
379
380     my $dbh = C4::Context->dbh;
381     my $sth = $dbh->prepare_cached("DELETE FROM borrower_attribute_types WHERE code = ?");
382     $sth->execute($code);
383 }
384
385 =head2 num_patrons
386
387 =over 4
388
389 my $count = $attr_type->num_patrons();
390
391 =back
392
393 Returns the number of patron records that use
394 this attribute type.
395
396 =cut
397
398 sub num_patrons {
399     my $self = shift;
400
401     my $dbh = C4::Context->dbh;
402     my $sth = $dbh->prepare_cached("SELECT COUNT(DISTINCT borrowernumber)
403                                     FROM borrower_attributes
404                                     WHERE code = ?");
405     $sth->execute($self->{code});
406     my ($count) = $sth->fetchrow_array;
407     $sth->finish;
408     return $count;
409 }
410
411 =head2 get_patrons
412
413 =over 4
414
415 my @borrowernumbers = $attr_type->get_patrons($attribute);
416
417 =back
418
419 Returns the borrowernumber of the patron records that
420 have an attribute with the specifie value.
421
422 =cut
423
424 sub get_patrons {
425     my $self = shift;
426     my $value = shift;
427
428     my $dbh = C4::Context->dbh;
429     my $sth = $dbh->prepare_cached("SELECT DISTINCT borrowernumber
430                                     FROM borrower_attributes
431                                     WHERE code = ?
432                                     AND   attribute = ?");
433     $sth->execute($self->{code}, $value);
434     my @results;
435     while (my ($borrowernumber) = $sth->fetchrow_array) {
436         push @results, $borrowernumber;
437     } 
438     return @results;
439 }
440
441 =head1 AUTHOR
442
443 Koha Development Team <http://koha-community.org/>
444
445 Galen Charlton <galen.charlton@liblime.com>
446
447 =cut
448
449 1;