Bug 3706 Label templates/layouts do not save properly
[koha.git] / C4 / Labels / Profile.pm
1 package C4::Labels::Profile;
2
3 use strict;
4 use warnings;
5
6 use C4::Context;
7 use C4::Debug;
8 use C4::Labels::Lib 1.000000 qw(get_unit_values);
9
10 BEGIN {
11     use version; our $VERSION = qv('1.0.0_1');
12 }
13
14 sub _check_params {
15     my $given_params = {};
16     my $exit_code = 0;
17     my @valid_profile_params = (
18         'printer_name',
19         'template_id',
20         'paper_bin',
21         'offset_horz',
22         'offset_vert',
23         'creep_horz',
24         'creep_vert',
25         'units',
26     );
27     if (scalar(@_) >1) {
28         $given_params = {@_};
29         foreach my $key (keys %{$given_params}) {
30             if (!(grep m/$key/, @valid_profile_params)) {
31                 warn sprintf('Unrecognized parameter type of "%s".', $key);
32                 $exit_code = 1;
33             }
34         }
35     }
36     else {
37         if (!(grep m/$_/, @valid_profile_params)) {
38             warn sprintf('Unrecognized parameter type of "%s".', $_);
39             $exit_code = 1;
40         }
41     }
42     return $exit_code;
43 }
44
45 sub _conv_points {
46     my $self = shift;
47     my @unit_value = grep {$_->{'type'} eq $self->{units}} @{get_unit_values()};
48     $self->{offset_horz}        = $self->{offset_horz} * $unit_value[0]->{'value'};
49     $self->{offset_vert}        = $self->{offset_vert} * $unit_value[0]->{'value'};
50     $self->{creep_horz}         = $self->{creep_horz} * $unit_value[0]->{'value'};
51     $self->{creep_vert}         = $self->{creep_vert} * $unit_value[0]->{'value'};
52     return $self;
53 }
54
55 sub new {
56     my $invocant = shift;
57     if (_check_params(@_) eq 1) {
58         return -1;
59     }
60     my $type = ref($invocant) || $invocant;
61     my $self = {
62         printer_name    => 'Default Printer',
63         template_id     => '',
64         paper_bin       => 'Tray 1',
65         offset_horz     => 0,
66         offset_vert     => 0,
67         creep_horz      => 0,
68         creep_vert      => 0,
69         units           => 'POINT',
70         @_,
71     };
72     bless ($self, $type);
73     return $self;
74 }
75
76 sub retrieve {
77     my $invocant = shift;
78     my %opts = @_;
79     my $type = ref($invocant) || $invocant;
80     my $query = "SELECT * FROM printers_profile WHERE profile_id = ?";
81     my $sth = C4::Context->dbh->prepare($query);
82     $sth->execute($opts{profile_id});
83     if ($sth->err) {
84         warn sprintf('Database returned the following error: %s', $sth->errstr);
85         return -1;
86     }
87     my $self = $sth->fetchrow_hashref;
88     $self = _conv_points($self) if ($opts{convert} && $opts{convert} == 1);
89     bless ($self, $type);
90     return $self;
91 }
92
93 sub delete {
94     my $self = {};
95     my %opts = ();
96     my $call_type = '';
97     my $query_param = '';
98     if (ref($_[0])) {
99         $self = shift;  # check to see if this is a method call
100         $call_type = 'C4::Labels::Profile->delete';
101         $query_param = $self->{'profile_id'};
102     }
103     else {
104         %opts = @_;
105         $call_type = 'C4::Labels::Profile::delete';
106         $query_param = $opts{'profile_id'};
107     }
108     if ($query_param eq '') {   # If there is no profile id then we cannot delete it
109         warn sprintf('%s : Cannot delete layout as the profile id is invalid or non-existant.', $call_type);
110         return -1;
111     }
112     my $query = "DELETE FROM printers_profile WHERE profile_id = ?";
113     my $sth = C4::Context->dbh->prepare($query);
114 #    $sth->{'TraceLevel'} = 3;
115     $sth->execute($query_param);
116 }
117
118 sub save {
119     my $self = shift;
120     if ($self->{'profile_id'}) {        # if we have an profile_id, the record exists and needs UPDATE
121         my @params;
122         my $query = "UPDATE printers_profile SET ";
123         foreach my $key (keys %{$self}) {
124             next if $key eq 'profile_id';
125             push (@params, $self->{$key});
126             $query .= "$key=?, ";
127         }
128         $query = substr($query, 0, (length($query)-2));
129         push (@params, $self->{'profile_id'});
130         $query .= " WHERE profile_id=?;";
131         my $sth = C4::Context->dbh->prepare($query);
132 #        $sth->{'TraceLevel'} = 3;
133         $sth->execute(@params);
134         if ($sth->err) {
135             warn sprintf('Database returned the following error on attempted UPDATE: %s', $sth->errstr);
136             return -1;
137         }
138         return $self->{'profile_id'};
139     }
140     else {                      # otherwise create a new record
141         my @params;
142         my $query = "INSERT INTO printers_profile (";
143         foreach my $key (keys %{$self}) {
144             push (@params, $self->{$key});
145             $query .= "$key, ";
146         }
147         $query = substr($query, 0, (length($query)-2));
148         $query .= ") VALUES (";
149         for (my $i=1; $i<=(scalar keys %$self); $i++) {
150             $query .= "?,";
151         }
152         $query = substr($query, 0, (length($query)-1));
153         $query .= ");";
154         my $sth = C4::Context->dbh->prepare($query);
155         $sth->execute(@params);
156         if ($sth->err) {
157             warn sprintf('Database returned the following error on attempted INSERT: %s', $sth->errstr);
158             return -1;
159         }
160         my $sth1 = C4::Context->dbh->prepare("SELECT MAX(profile_id) FROM printers_profile;");
161         $sth1->execute();
162         my $tmpl_id = $sth1->fetchrow_array;
163         return $tmpl_id;
164     }
165 }
166
167 sub get_attr {
168     my $self = shift;
169     if (_check_params(@_) eq 1) {
170         return -1;
171     }
172     my ($attr) = @_;
173     if (exists($self->{$attr})) {
174         return $self->{$attr};
175     }
176     else {
177         warn sprintf('%s is currently undefined.', $attr);
178         return -1;
179     }
180 }
181
182 sub set_attr {
183     my $self = shift;
184     if (_check_params(@_) eq 1) {
185         return -1;
186     }
187     my %attrs = @_;
188     foreach my $attrib (keys(%attrs)) {
189         $self->{$attrib} = $attrs{$attrib};
190     };
191     return 0;
192 }
193
194 1;
195 __END__
196
197 =head1 NAME
198
199 C4::Labels::Profile - A class for creating and manipulating profile objects in Koha
200
201 =head1 ABSTRACT
202
203 This module provides methods for creating, retrieving, and otherwise manipulating label profile objects used by Koha to create and export labels.
204
205 =head1 METHODS
206
207 =head2 new()
208
209     Invoking the I<new> method constructs a new profile object containing the default values for a template.
210     The following parameters are optionally accepted as key => value pairs:
211
212         C<printer_name>         The name of the printer to which this profile applies.
213         C<template_id>          The template to which this profile may be applied. NOTE: There may be multiple profiles which may be applied to the same template.
214         C<paper_bin>            The paper bin of the above printer to which this profile applies. NOTE: printer name, template id, and paper bin must form a unique combination.
215         C<offset_horz>          Amount of compensation for horizontal offset (position of text on a single label). This amount is measured in the units supplied by the units parameter in this profile.
216         C<offset_vert>          Amount of compensation for vertical offset.
217         C<creep_horz>           Amount of compensation for horizontal creep (tendency of text to 'creep' off of the labels over the span of the entire page).
218         C<creep_vert>           Amount of compensation for vertical creep.
219         C<units>                The units of measure used for this template. These B<must> match the measures you supply above or
220                                 bad things will happen to your document. NOTE: The only supported units at present are:
221
222 =over 9
223
224 =item .
225 POINT   = Postscript Points (This is the base unit in the Koha label creator.)
226
227 =item .
228 AGATE   = Adobe Agates (5.1428571 points per)
229
230 =item .
231 INCH    = US Inches (72 points per)
232
233 =item .
234 MM      = SI Millimeters (2.83464567 points per)
235
236 =item .
237 CM      = SI Centimeters (28.3464567 points per)
238
239 =back
240
241     example:
242         C<my $profile = C4::Labels::Profile->new(); # Creates and returns a new profile object>
243
244         C<my $profile = C4::Labels::Profile->new(template_id => 1, paper_bin => 'Bypass Tray', offset_horz => 0.02, units => 'POINT'); # Creates and returns a new profile object using
245             the supplied values to override the defaults>
246
247     B<NOTE:> This profile is I<not> written to the database until save() is invoked. You have been warned!
248
249 =head2 retrieve(profile_id => $profile_id, convert => 1)
250
251     Invoking the I<retrieve> method constructs a new profile object containing the current values for profile_id. The method returns a new object upon success and 1 upon failure.
252     Errors are logged to the Apache log. One further option maybe accessed. See the examples below for further description.
253
254     examples:
255
256         C<my $profile = C4::Labels::Profile->retrieve(profile_id => 1); # Retrieves profile record 1 and returns an object containing the record>
257
258         C<my $profile = C4::Labels::Profile->retrieve(profile_id => 1, convert => 1); # Retrieves profile record 1, converts the units to points and returns an object containing the record>
259
260 =head2 delete()
261
262     Invoking the delete method attempts to delete the profile from the database. The method returns -1 upon failure. Errors are logged to the Apache log.
263     NOTE: This method may also be called as a function and passed a key/value pair simply deleteing that profile from the database. See the example below.
264
265     examples:
266         C<my $exitstat = $profile->delete(); # to delete the record behind the $profile object>
267         C<my $exitstat = C4::Labels::Profile::delete(profile_id => 1); # to delete profile record 1>
268
269 =head2 save()
270
271     Invoking the I<save> method attempts to insert the profile into the database if the profile is new and update the existing profile record if the profile exists. The method returns
272     the new record profile_id upon success and -1 upon failure (This avoids conflicting with a record profile_id of 1). Errors are logged to the Apache log.
273
274     example:
275         C<my $exitstat = $profile->save(); # to save the record behind the $profile object>
276
277 =head2 get_attr($attribute)
278
279     Invoking the I<get_attr> method will return the value of the requested attribute or -1 on errors.
280
281     example:
282         C<my $value = $profile->get_attr($attribute);>
283
284 =head2 set_attr(attribute => value, attribute_2 => value)
285
286     Invoking the I<set_attr> method will set the value of the supplied attributes to the supplied values. The method accepts key/value pairs separated by commas.
287
288     example:
289         $profile->set_attr(attribute => value);
290
291 =head1 AUTHOR
292
293 Chris Nighswonger <cnighswonger AT foundations DOT edu>
294
295 =head1 COPYRIGHT
296
297 Copyright 2009 Foundations Bible College.
298
299 =head1 LICENSE
300
301 This file is part of Koha.
302
303 Koha is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
304 Foundation; either version 2 of the License, or (at your option) any later version.
305
306 You should have received a copy of the GNU General Public License along with Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
307 Suite 330, Boston, MA  02111-1307 USA
308
309 =head1 DISCLAIMER OF WARRANTY
310
311 Koha is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
312 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
313
314 =cut
315
316 #=head1
317 #drawbox( ($left_margin), ($top_margin), ($page_width-(2*$left_margin)), ($page_height-(2*$top_margin)) ); # FIXME: Breakout code to print alignment page for printer profile setup
318 #
319 #=head2 draw_boundaries
320 #
321 # sub draw_boundaries ($llx_spine, $llx_circ1, $llx_circ2,
322 #                $lly, $spine_width, $label_height, $circ_width)
323 #
324 #This sub draws boundary lines where the label outlines are, to aid in printer testing, and debugging.
325 #
326 #=cut
327 #
328 ##       FIXME: Template use for profile adjustment...
329 ##sub draw_boundaries {
330 ##
331 ##    my (
332 ##        $llx_spine, $llx_circ1,  $llx_circ2, $lly,
333 ##        $spine_width, $label_height, $circ_width
334 ##    ) = @_;
335 ##
336 ##    my $lly_initial = ( ( 792 - 36 ) - 90 );
337 ##    $lly            = $lly_initial; # FIXME - why are we ignoring the y_pos parameter by redefining it?
338 ##    my $i             = 1;
339 ##
340 ##    for ( $i = 1 ; $i <= 8 ; $i++ ) {
341 ##
342 ##        _draw_box( $llx_spine, $lly, ($spine_width), ($label_height) );
343 ##
344 ##   #warn "OLD BOXES  x=$llx_spine, y=$lly, w=$spine_width, h=$label_height";
345 ##        _draw_box( $llx_circ1, $lly, ($circ_width), ($label_height) );
346 ##        _draw_box( $llx_circ2, $lly, ($circ_width), ($label_height) );
347 ##
348 ##        $lly = ( $lly - $label_height );
349 ##
350 ##    }
351 ##}
352 #
353 #
354 #
355 #=cut