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