Bug 10855: Squash several fixes
[koha.git] / Koha / AdditionalField.pm
blob2f3f44bc603de763035538b90fc37250aaa21eb9
1 package Koha::AdditionalField;
3 use Modern::Perl;
5 use base qw(Class::Accessor);
7 use C4::Context;
9 __PACKAGE__->mk_accessors(qw( id tablename name authorised_value_category marcfield searchable values ));
11 sub new {
12 my ( $class, $args ) = @_;
14 my $additional_field = {
15 id => $args->{id} // q||,
16 tablename => $args->{tablename} // q||,
17 name => $args->{name} // q||,
18 authorised_value_category => $args->{authorised_value_category} // q||,
19 marcfield => $args->{marcfield} // q||,
20 searchable => $args->{searchable} // 0,
21 values => $args->{values} // {},
24 my $self = $class->SUPER::new( $additional_field );
26 bless $self, $class;
27 return $self;
30 sub fetch {
31 my ( $self ) = @_;
32 my $dbh = C4::Context->dbh;
33 my $field_id = $self->id;
34 return unless $field_id;
35 my $data = $dbh->selectrow_hashref(
37 SELECT id, tablename, name, authorised_value_category, marcfield, searchable
38 FROM additional_fields
39 WHERE id = ?
41 {}, ( $field_id )
44 die "This additional field does not exist (id=$field_id)" unless $data;
45 $self->{id} = $data->{id};
46 $self->{tablename} = $data->{tablename};
47 $self->{name} = $data->{name};
48 $self->{authorised_value_category} = $data->{authorised_value_category};
49 $self->{marcfield} = $data->{marcfield};
50 $self->{searchable} = $data->{searchable};
51 return $self;
54 sub update {
55 my ( $self ) = @_;
57 die "There is no id defined for this additional field. I cannot update it" unless $self->{id};
59 my $dbh = C4::Context->dbh;
60 local $dbh->{RaiseError} = 1;
62 return $dbh->do(q|
63 UPDATE additional_fields
64 SET name = ?,
65 authorised_value_category = ?,
66 marcfield = ?,
67 searchable = ?
68 WHERE id = ?
69 |, {}, ( $self->{name}, $self->{authorised_value_category}, $self->{marcfield}, $self->{searchable}, $self->{id} ) );
72 sub delete {
73 my ( $self ) = @_;
74 return unless $self->{id};
75 my $dbh = C4::Context->dbh;
76 local $dbh->{RaiseError} = 1;
77 return $dbh->do(q|
78 DELETE FROM additional_fields WHERE id = ?
79 |, {}, ( $self->{id} ) );
82 sub insert {
83 my ( $self ) = @_;
84 my $dbh = C4::Context->dbh;
85 local $dbh->{RaiseError} = 1;
86 $dbh->do(q|
87 INSERT INTO additional_fields
88 ( tablename, name, authorised_value_category, marcfield, searchable )
89 VALUES ( ?, ?, ?, ?, ? )
90 |, {}, ( $self->{tablename}, $self->{name}, $self->{authorised_value_category}, $self->{marcfield}, $self->{searchable} ) );
91 $self->{id} = $dbh->{mysql_insertid};
94 sub insert_values {
95 my ( $self ) = @_;
97 my $dbh = C4::Context->dbh;
98 local $dbh->{RaiseError} = 1;
99 while ( my ( $record_id, $value ) = each %{$self->{values}} ) {
100 next unless defined $value;
101 my $updated = $dbh->do(q|
102 UPDATE additional_field_values
103 SET value = ?
104 WHERE field_id = ?
105 AND record_id = ?
106 |, {}, ( $value, $self->{id}, $record_id ));
107 if ( $updated eq '0E0' ) {
108 $dbh->do(q|
109 INSERT INTO additional_field_values( field_id, record_id, value )
110 VALUES( ?, ?, ?)
111 |, {}, ( $self->{id}, $record_id, $value ));
116 sub fetch_values {
117 my ( $self, $args ) = @_;
118 my $record_id = $args->{record_id};
119 my $dbh = C4::Context->dbh;
120 my $values = $dbh->selectall_arrayref(
122 SELECT *
123 FROM additional_fields af, additional_field_values afv
124 WHERE af.id = afv.field_id
125 AND af.tablename = ?
126 AND af.name = ?
127 | . ( $record_id ? q|AND afv.record_id = ?| : '' ),
128 {Slice => {}}, ( $self->{tablename}, $self->{name}, ($record_id ? $record_id : () ) )
131 $self->{values} = {};
132 for my $v ( @$values ) {
133 $self->{values}{$v->{record_id}} = $v->{value};
137 sub all {
138 my ( $class, $args ) = @_;
139 die "BAD CALL: Don't use fetch_all_values as an instance method"
140 if ref $class and UNIVERSAL::can($class,'can');
141 my $tablename = $args->{tablename};
142 my $searchable = $args->{searchable};
143 my $dbh = C4::Context->dbh;
144 my $query = q|
145 SELECT * FROM additional_fields WHERE 1
147 $query .= q| AND tablename = ?|
148 if $tablename;
150 $query .= q| AND searchable = ?|
151 if defined $searchable;
153 my $results = $dbh->selectall_arrayref(
154 $query, {Slice => {}}, (
155 $tablename ? $tablename : (),
156 defined $searchable ? $searchable : ()
159 my @fields;
160 for my $r ( @$results ) {
161 push @fields, Koha::AdditionalField->new({
162 id => $r->{id},
163 tablename => $r->{tablename},
164 name => $r->{name},
165 authorised_value_category => $r->{authorised_value_category},
166 marcfield => $r->{marcfield},
167 searchable => $r->{searchable},
170 return \@fields;
174 sub fetch_all_values {
175 my ( $class, $args ) = @_;
176 die "BAD CALL: Don't use fetch_all_values as an instance method"
177 if ref $class and UNIVERSAL::can($class,'can');
179 my $record_id = $args->{record_id};
180 my $tablename = $args->{tablename};
181 return unless $tablename;
183 my $dbh = C4::Context->dbh;
184 my $values = $dbh->selectall_arrayref(
186 SELECT afv.record_id, af.name, afv.value
187 FROM additional_fields af, additional_field_values afv
188 WHERE af.id = afv.field_id
189 AND af.tablename = ?
190 | . ( $record_id ? q| AND afv.record_id = ?| : q|| ),
191 {Slice => {}}, ( $tablename, ($record_id ? $record_id : ()) )
194 my $r;
195 for my $v ( @$values ) {
196 $r->{$v->{record_id}}{$v->{name}} = $v->{value};
198 return $r;
201 sub get_matching_record_ids {
202 my ( $class, $args ) = @_;
203 die "BAD CALL: Don't use fetch_all_values as an instance method"
204 if ref $class and UNIVERSAL::can($class,'can');
206 my $fields = $args->{fields} // [];
207 my $tablename = $args->{tablename};
208 my $exact_match = $args->{exact_match} // 1;
209 return [] unless @$fields;
211 my $dbh = C4::Context->dbh;
212 my $query = q|SELECT * FROM |;
213 my ( @subqueries, @args );
214 my $i = 0;
215 for my $field ( @$fields ) {
216 $i++;
217 my $subquery = qq|(
218 SELECT record_id, field$i.name AS field${i}_name
219 FROM additional_field_values afv
220 LEFT JOIN
222 SELECT afv.id, af.name, afv.value
223 FROM additional_field_values afv, additional_fields af
224 WHERE afv.field_id = af.id
225 AND af.name = ?
226 AND af.tablename = ?
227 AND value LIKE ?
228 ) AS field$i USING (id)
229 WHERE field$i.id IS NOT NULL
230 ) AS values$i |;
231 $subquery .= ' USING (record_id)' if $i > 1;
232 push @subqueries, $subquery;
233 push @args, $field->{name}, $tablename, ( $exact_match ? $field->{value} : "%$field->{value}%" );
235 $query .= join( ' LEFT JOIN ', @subqueries ) . ' WHERE 1';
236 for my $j ( 1 .. $i ) {
237 $query .= qq| AND field${j}_name IS NOT NULL|;
239 my $values = $dbh->selectall_arrayref( $query, {Slice => {}}, @args );
240 return [
241 map { $_->{record_id} } @$values
247 __END__
249 =head1 NAME
251 Koha::AdditionalField
253 =head1 SYNOPSIS
255 use Koha::AdditionalField;
256 my $af1 = Koha::AdditionalField->new({id => $id});
257 my $af2 = Koha::AuthorisedValue->new({
258 tablename => 'my_table',
259 name => 'a_name',
260 authorised_value_category => 'LOST',
261 marcfield => '200$a',
262 searchable => 1,
264 $av1->delete;
265 $av2->{name} = 'another_name';
266 $av2->update;
268 =head1 DESCRIPTION
270 Class for managing additional fields into Koha.
272 =head1 METHODS
274 =head2 new
276 Create a new Koha::AdditionalField object. This method can be called using several ways.
277 Either with the id for existing field or with different values for a new one.
279 =over 4
281 =item B<id>
283 The caller just knows the id of the additional field and want to retrieve all values.
285 =item B<tablename, name, authorised_value_category, marcfield and searchable>
287 The caller wants to create a new additional field.
289 =back
291 =head2 fetch
293 The information will be retrieved from the database.
295 =head2 update
297 If the AdditionalField object has been modified and the values have to be modified into the database, call this method.
299 =head2 delete
301 Remove a the record in the database using the id the object.
303 =head2 insert
305 Insert a new AdditionalField object into the database.
307 =head2 insert_values
309 Insert new values for a record.
311 my $af = Koha::AdditionalField({ id => $id })->fetch;
312 my $af->{values} = {
313 record_id1 => 'my value',
314 record_id2 => 'another value',
316 $af->insert_values;
318 =head2 fetch_values
320 Retrieve values from the database for a given record_id.
321 The record_id argument is optional.
323 my $af = Koha::AdditionalField({ id => $id })->fetch;
324 my $values = $af->fetch_values({record_id => $record_id});
326 $values will be equal to something like:
328 record_id => {
329 field_name1 => 'value1',
330 field_name2 => 'value2',
334 =head2 all
336 Retrieve all additional fields in the database given some parameters.
337 Parameters are optional.
338 This method returns a list of AdditionalField objects.
339 This is a static method.
341 my $fields = Koha::AdditionalField->all;
343 my $fields = Koha::AdditionalField->all{(tablename => 'my_table'});
345 my $fields = Koha::AdditionalField->all({searchable => 1});
347 =head2 fetch_all_values
349 Retrieve all values for a table name.
350 This is a static method.
352 my $values = Koha::AdditionalField({ tablename => 'my_table' });
354 $values will be equel to something like:
356 record_id1 => {
357 field_name1 => 'value1',
358 field_name2 => 'value2',
360 record_id2 => {
361 field_name1 => 'value3',
362 field_name2 => 'value4',
367 =head2 get_matching_record_ids
369 Retrieve all record_ids for records matching the field values given in parameter.
370 This method returns a list of ids.
371 This is a static method.
373 my $fields = [
375 name => 'field_name',
376 value => 'field_value',
379 my $ids = Koha::AdditionalField->get_matching_record_ids(
381 tablename => 'subscription',
382 fields => $fields
386 =head1 AUTHOR
388 Jonathan Druart <jonathan.druart at biblibre.com>
390 =head1 COPYRIGHT
392 Copyright 2013 BibLibre
394 =head1 LICENSE
396 This file is part of Koha.
398 Koha is free software; you can redistribute it and/or modify it under the
399 terms of the GNU General Public License as published by the Free Software
400 Foundation; either version 3 of the License, or (at your option) any later
401 version.
403 Koha is distributed in the hope that it will be useful, but WITHOUT ANY
404 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
405 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
407 You should have received a copy of the GNU General Public License along
408 with Koha; if not, see <http://www.gnu.org/licenses>.