File: | C4/Members/AttributeTypes.pm |
Coverage: | 7.0% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
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 | 16 16 16 | 513 142 557 | use strict; | |||
21 | #use warnings; FIXME - Bug 2505 | |||||
22 | 16 16 16 | 406 96 233 | use C4::Context; | |||
23 | ||||||
24 | 16 16 16 | 140 86 895 | use vars qw($VERSION); | |||
25 | ||||||
26 | BEGIN { | |||||
27 | # set the version for version checking | |||||
28 | 16 | 27737 | $VERSION = 3.00; | |||
29 | } | |||||
30 | ||||||
31 - 69 | =head1 NAME C4::Members::AttributeTypes - mananage extended patron attribute types =head1 SYNOPSIS my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes(); my $attr_type = C4::Members::AttributeTypes->new($code, $description); $attr_type->code($code); $attr_type->description($description); $attr_type->repeatable($repeatable); $attr_type->unique_id($unique_id); $attr_type->opac_display($opac_display); $attr_type->password_allowed($password_allowed); $attr_type->staff_searchable($staff_searchable); $attr_type->authorised_value_category($authorised_value_category); $attr_type->store(); $attr_type->delete(); my $attr_type = C4::Members::AttributeTypes->fetch($code); $attr_type = C4::Members::AttributeTypes->delete($code); =head1 FUNCTIONS =head2 GetAttributeTypes my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes($all_fields); Returns an array of hashrefs of each attribute type defined in the database. The array is sorted by code. Each hashref contains at least the following fields: - code - description If $all_fields is true, then each hashref also contains the other fields from borrower_attribute_types. =cut | |||||
70 | ||||||
71 | sub GetAttributeTypes { | |||||
72 | 0 | my ($all) = @_; | ||||
73 | 0 | my $select = $all ? '*' : 'code, description, class'; | ||||
74 | 0 | my $dbh = C4::Context->dbh; | ||||
75 | 0 | my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code"); | ||||
76 | 0 | $sth->execute(); | ||||
77 | 0 | my $results = $sth->fetchall_arrayref({}); | ||||
78 | 0 | return @$results; | ||||
79 | } | |||||
80 | ||||||
81 | sub GetAttributeTypes_hashref { | |||||
82 | 0 0 | my %hash = map {$_->{code} => $_} GetAttributeTypes(@_); | ||||
83 | 0 | return \%hash; | ||||
84 | } | |||||
85 | ||||||
86 - 93 | =head2 AttributeTypeExists my $have_attr_xyz = C4::Members::AttributeTypes::AttributeTypeExists($code) Returns true if we have attribute type C<$code> in the database. =cut | |||||
94 | ||||||
95 | sub AttributeTypeExists { | |||||
96 | 0 | my ($code) = @_; | ||||
97 | 0 | my $dbh = C4::Context->dbh; | ||||
98 | 0 | my $exists = $dbh->selectrow_array("SELECT code FROM borrower_attribute_types WHERE code = ?", undef, $code); | ||||
99 | 0 | return $exists; | ||||
100 | } | |||||
101 | ||||||
102 - 108 | =head1 METHODS my $attr_type = C4::Members::AttributeTypes->new($code, $description); Create a new attribute type. =cut | |||||
109 | ||||||
110 | sub new { | |||||
111 | 0 | my $class = shift; | ||||
112 | 0 | my $self = {}; | ||||
113 | ||||||
114 | 0 | $self->{'code'} = shift; | ||||
115 | 0 | $self->{'description'} = shift; | ||||
116 | 0 | $self->{'repeatable'} = 0; | ||||
117 | 0 | $self->{'unique_id'} = 0; | ||||
118 | 0 | $self->{'opac_display'} = 0; | ||||
119 | 0 | $self->{'password_allowed'} = 0; | ||||
120 | 0 | $self->{'staff_searchable'} = 0; | ||||
121 | 0 | $self->{'display_checkout'} = 0; | ||||
122 | 0 | $self->{'authorised_value_category'} = ''; | ||||
123 | 0 | $self->{'category_code'} = ''; | ||||
124 | 0 | $self->{'category_description'} = ''; | ||||
125 | 0 | $self->{'class'} = ''; | ||||
126 | ||||||
127 | 0 | bless $self, $class; | ||||
128 | 0 | return $self; | ||||
129 | } | |||||
130 | ||||||
131 - 138 | =head2 fetch my $attr_type = C4::Members::AttributeTypes->fetch($code); Fetches an attribute type from the database. If no type with the given C<$code> exists, returns undef. =cut | |||||
139 | ||||||
140 | sub fetch { | |||||
141 | 0 | my $class = shift; | ||||
142 | 0 | my $code = shift; | ||||
143 | 0 | my $self = {}; | ||||
144 | 0 | my $dbh = C4::Context->dbh(); | ||||
145 | ||||||
146 | 0 | my $sth = $dbh->prepare_cached(" | ||||
147 | SELECT borrower_attribute_types.*, categories.description AS category_description | |||||
148 | FROM borrower_attribute_types | |||||
149 | LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode | |||||
150 | WHERE code =?"); | |||||
151 | 0 | $sth->execute($code); | ||||
152 | 0 | my $row = $sth->fetchrow_hashref; | ||||
153 | 0 | $sth->finish(); | ||||
154 | 0 | return undef unless defined $row; | ||||
155 | ||||||
156 | 0 | $self->{'code'} = $row->{'code'}; | ||||
157 | 0 | $self->{'description'} = $row->{'description'}; | ||||
158 | 0 | $self->{'repeatable'} = $row->{'repeatable'}; | ||||
159 | 0 | $self->{'unique_id'} = $row->{'unique_id'}; | ||||
160 | 0 | $self->{'opac_display'} = $row->{'opac_display'}; | ||||
161 | 0 | $self->{'password_allowed'} = $row->{'password_allowed'}; | ||||
162 | 0 | $self->{'staff_searchable'} = $row->{'staff_searchable'}; | ||||
163 | 0 | $self->{'display_checkout'} = $row->{'display_checkout'}; | ||||
164 | 0 | $self->{'authorised_value_category'} = $row->{'authorised_value_category'}; | ||||
165 | 0 | $self->{'category_code'} = $row->{'category_code'}; | ||||
166 | 0 | $self->{'category_description'} = $row->{'category_description'}; | ||||
167 | 0 | $self->{'class'} = $row->{'class'}; | ||||
168 | ||||||
169 | 0 | bless $self, $class; | ||||
170 | 0 | return $self; | ||||
171 | } | |||||
172 | ||||||
173 - 181 | =head2 store $attr_type->store(); Stores attribute type in the database. If the type previously retrieved from the database via the fetch() method, the DB representation of the type is replaced. =cut | |||||
182 | ||||||
183 | sub store { | |||||
184 | 0 | my $self = shift; | ||||
185 | ||||||
186 | 0 | my $dbh = C4::Context->dbh; | ||||
187 | 0 | my $sth; | ||||
188 | 0 | my $existing = __PACKAGE__->fetch($self->{'code'}); | ||||
189 | 0 | if (defined $existing) { | ||||
190 | 0 | $sth = $dbh->prepare_cached("UPDATE borrower_attribute_types | ||||
191 | SET description = ?, | |||||
192 | repeatable = ?, | |||||
193 | unique_id = ?, | |||||
194 | opac_display = ?, | |||||
195 | password_allowed = ?, | |||||
196 | staff_searchable = ?, | |||||
197 | authorised_value_category = ?, | |||||
198 | display_checkout = ?, | |||||
199 | category_code = ?, | |||||
200 | class = ? | |||||
201 | WHERE code = ?"); | |||||
202 | } else { | |||||
203 | 0 | $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types | ||||
204 | (description, repeatable, unique_id, opac_display, password_allowed, | |||||
205 | staff_searchable, authorised_value_category, display_checkout, category_code, class, code) | |||||
206 | VALUES (?, ?, ?, ?, ?, | |||||
207 | ?, ?, ?, ?, ?, ?)"); | |||||
208 | } | |||||
209 | 0 | $sth->bind_param(1, $self->{'description'}); | ||||
210 | 0 | $sth->bind_param(2, $self->{'repeatable'}); | ||||
211 | 0 | $sth->bind_param(3, $self->{'unique_id'}); | ||||
212 | 0 | $sth->bind_param(4, $self->{'opac_display'}); | ||||
213 | 0 | $sth->bind_param(5, $self->{'password_allowed'}); | ||||
214 | 0 | $sth->bind_param(6, $self->{'staff_searchable'}); | ||||
215 | 0 | $sth->bind_param(7, $self->{'authorised_value_category'}); | ||||
216 | 0 | $sth->bind_param(8, $self->{'display_checkout'}); | ||||
217 | 0 | $sth->bind_param(9, $self->{'category_code'} || undef); | ||||
218 | 0 | $sth->bind_param(10, $self->{'class'}); | ||||
219 | 0 | $sth->bind_param(11, $self->{'code'}); | ||||
220 | 0 | $sth->execute; | ||||
221 | ||||||
222 | } | |||||
223 | ||||||
224 - 232 | =head2 code my $code = $attr_type->code(); $attr_type->code($code); Accessor. Note that the code is immutable once a type is created or fetched from the database. =cut | |||||
233 | ||||||
234 | sub code { | |||||
235 | 0 | my $self = shift; | ||||
236 | 0 | return $self->{'code'}; | ||||
237 | } | |||||
238 | ||||||
239 - 246 | =head2 description my $description = $attr_type->description(); $attr_type->description($description); Accessor. =cut | |||||
247 | ||||||
248 | sub description { | |||||
249 | 0 | my $self = shift; | ||||
250 | 0 | @_ ? $self->{'description'} = shift : $self->{'description'}; | ||||
251 | } | |||||
252 | ||||||
253 - 261 | =head2 repeatable my $repeatable = $attr_type->repeatable(); $attr_type->repeatable($repeatable); Accessor. The C<$repeatable> argument is interpreted as a Perl boolean. =cut | |||||
262 | ||||||
263 | sub repeatable { | |||||
264 | 0 | my $self = shift; | ||||
265 | 0 | @_ ? $self->{'repeatable'} = ((shift) ? 1 : 0) : $self->{'repeatable'}; | ||||
266 | } | |||||
267 | ||||||
268 - 276 | =head2 unique_id my $unique_id = $attr_type->unique_id(); $attr_type->unique_id($unique_id); Accessor. The C<$unique_id> argument is interpreted as a Perl boolean. =cut | |||||
277 | ||||||
278 | sub unique_id { | |||||
279 | 0 | my $self = shift; | ||||
280 | 0 | @_ ? $self->{'unique_id'} = ((shift) ? 1 : 0) : $self->{'unique_id'}; | ||||
281 | } | |||||
282 - 290 | =head2 opac_display my $opac_display = $attr_type->opac_display(); $attr_type->opac_display($opac_display); Accessor. The C<$opac_display> argument is interpreted as a Perl boolean. =cut | |||||
291 | ||||||
292 | sub opac_display { | |||||
293 | 0 | my $self = shift; | ||||
294 | 0 | @_ ? $self->{'opac_display'} = ((shift) ? 1 : 0) : $self->{'opac_display'}; | ||||
295 | } | |||||
296 - 304 | =head2 password_allowed my $password_allowed = $attr_type->password_allowed(); $attr_type->password_allowed($password_allowed); Accessor. The C<$password_allowed> argument is interpreted as a Perl boolean. =cut | |||||
305 | ||||||
306 | sub password_allowed { | |||||
307 | 0 | my $self = shift; | ||||
308 | 0 | @_ ? $self->{'password_allowed'} = ((shift) ? 1 : 0) : $self->{'password_allowed'}; | ||||
309 | } | |||||
310 - 318 | =head2 staff_searchable my $staff_searchable = $attr_type->staff_searchable(); $attr_type->staff_searchable($staff_searchable); Accessor. The C<$staff_searchable> argument is interpreted as a Perl boolean. =cut | |||||
319 | ||||||
320 | sub staff_searchable { | |||||
321 | 0 | my $self = shift; | ||||
322 | 0 | @_ ? $self->{'staff_searchable'} = ((shift) ? 1 : 0) : $self->{'staff_searchable'}; | ||||
323 | } | |||||
324 | ||||||
325 - 337 | =head2 display_checkout =over 4 my $display_checkout = $attr_type->display_checkout(); $attr_type->display_checkout($display_checkout); =back Accessor. The C<$display_checkout> argument is interpreted as a Perl boolean. =cut | |||||
338 | ||||||
339 | sub display_checkout { | |||||
340 | 0 | my $self = shift; | ||||
341 | 0 | @_ ? $self->{'display_checkout'} = ((shift) ? 1 : 0) : $self->{'display_checkout'}; | ||||
342 | } | |||||
343 | ||||||
344 - 351 | =head2 authorised_value_category my $authorised_value_category = $attr_type->authorised_value_category(); $attr_type->authorised_value_category($authorised_value_category); Accessor. =cut | |||||
352 | ||||||
353 | sub authorised_value_category { | |||||
354 | 0 | my $self = shift; | ||||
355 | 0 | @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'}; | ||||
356 | } | |||||
357 | ||||||
358 - 369 | =head2 category_code =over 4 my $category_code = $attr_type->category_code(); $attr_type->category_code($category_code); =back Accessor. =cut | |||||
370 | ||||||
371 | sub category_code { | |||||
372 | 0 | my $self = shift; | ||||
373 | 0 | @_ ? $self->{'category_code'} = shift : $self->{'category_code'}; | ||||
374 | } | |||||
375 | ||||||
376 - 387 | =head2 category_description =over 4 my $category_description = $attr_type->category_description(); $attr_type->category_description($category_description); =back Accessor. =cut | |||||
388 | ||||||
389 | sub category_description { | |||||
390 | 0 | my $self = shift; | ||||
391 | 0 | @_ ? $self->{'category_description'} = shift : $self->{'category_description'}; | ||||
392 | } | |||||
393 | ||||||
394 - 405 | =head2 class =over 4 my $class = $attr_type->class(); $attr_type->class($class); =back Accessor. =cut | |||||
406 | ||||||
407 | sub class { | |||||
408 | 0 | my $self = shift; | ||||
409 | 0 | @_ ? $self->{'class'} = shift : $self->{'class'}; | ||||
410 | } | |||||
411 | ||||||
412 | ||||||
413 - 421 | =head2 delete $attr_type->delete(); C4::Members::AttributeTypes->delete($code); Delete an attribute type from the database. The attribute type may be specified either by an object or by a code. =cut | |||||
422 | ||||||
423 | sub delete { | |||||
424 | 0 | my $arg = shift; | ||||
425 | 0 | my $code; | ||||
426 | 0 | if (ref($arg) eq __PACKAGE__) { | ||||
427 | 0 | $code = $arg->{'code'}; | ||||
428 | } else { | |||||
429 | 0 | $code = shift; | ||||
430 | } | |||||
431 | ||||||
432 | 0 | my $dbh = C4::Context->dbh; | ||||
433 | 0 | my $sth = $dbh->prepare_cached("DELETE FROM borrower_attribute_types WHERE code = ?"); | ||||
434 | 0 | $sth->execute($code); | ||||
435 | } | |||||
436 | ||||||
437 - 444 | =head2 num_patrons my $count = $attr_type->num_patrons(); Returns the number of patron records that use this attribute type. =cut | |||||
445 | ||||||
446 | sub num_patrons { | |||||
447 | 0 | my $self = shift; | ||||
448 | ||||||
449 | 0 | my $dbh = C4::Context->dbh; | ||||
450 | 0 | my $sth = $dbh->prepare_cached("SELECT COUNT(DISTINCT borrowernumber) | ||||
451 | FROM borrower_attributes | |||||
452 | WHERE code = ?"); | |||||
453 | 0 | $sth->execute($self->{code}); | ||||
454 | 0 | my ($count) = $sth->fetchrow_array; | ||||
455 | 0 | $sth->finish; | ||||
456 | 0 | return $count; | ||||
457 | } | |||||
458 | ||||||
459 - 466 | =head2 get_patrons my @borrowernumbers = $attr_type->get_patrons($attribute); Returns the borrowernumber of the patron records that have an attribute with the specifie value. =cut | |||||
467 | ||||||
468 | sub get_patrons { | |||||
469 | 0 | my $self = shift; | ||||
470 | 0 | my $value = shift; | ||||
471 | ||||||
472 | 0 | my $dbh = C4::Context->dbh; | ||||
473 | 0 | my $sth = $dbh->prepare_cached("SELECT DISTINCT borrowernumber | ||||
474 | FROM borrower_attributes | |||||
475 | WHERE code = ? | |||||
476 | AND attribute = ?"); | |||||
477 | 0 | $sth->execute($self->{code}, $value); | ||||
478 | 0 | my @results; | ||||
479 | 0 | while (my ($borrowernumber) = $sth->fetchrow_array) { | ||||
480 | 0 | push @results, $borrowernumber; | ||||
481 | } | |||||
482 | 0 | return @results; | ||||
483 | } | |||||
484 | ||||||
485 - 491 | =head1 AUTHOR Koha Development Team <http://koha-community.org/> Galen Charlton <galen.charlton@liblime.com> =cut | |||||
492 | ||||||
493 | 1; |