File Coverage

blib/lib/HTML/FormEngine/Checks.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             HTML::FormEngine::Checks - collection of FormEngine check routines
4              
5             =head1 CHECK ROUTINES
6              
7             B: all error messages are passed through gettext, that means if
8             you configured you locales e.g. to german you get the corresponding
9             german error message instead of the english messages which are
10             mentioned here. Read L and
11             L on how to overwrite the default error
12             messages with your own in the form configuration.
13              
14             =cut
15              
16             ######################################################################
17              
18             package HTML::FormEngine::Checks;
19              
20 1     1   5 use Locale::gettext;
  1         2  
  1         121  
21 1     1   661 use Date::Pcalc qw(check_date);
  0            
  0            
22              
23             ######################################################################
24              
25             =head2 not_null
26              
27             Returns I if the field wasn't filled.
28              
29             =cut
30              
31             ######################################################################
32              
33             sub _check_not_null {
34             my($value) = @_;
35             return gettext('value missing').'!' if(!defined($value) or (ref($value) eq 'ARRAY' and !@{$value}) or $value eq '');
36             }
37              
38             ######################################################################
39              
40             =head2 email
41              
42             Returns I if the format of the field value seems to be
43             incompatible to an email address. A simple regular expression is used
44             here , so far it matches the common email addresses. But it isn't
45             compatible to any standard. Use C if you want to check for RFC
46             compatible address format.
47              
48             Here is the used regexp, please inform me if you discover any bugs:
49              
50             C<^[A-Za-z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$>
51              
52             =cut
53              
54             ######################################################################
55              
56             sub _check_email {
57             my ($value) = @_;
58             return '' unless($value ne '');
59             # better use rfc822!
60             if(! ($value =~ m/^[A-Za-z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/)) {
61             return gettext('invalid').'!';
62             }
63             }
64              
65             ######################################################################
66              
67             =head2 rfc822
68              
69             Returns I if the given field value doesn't
70             match the RFC 822 specification. In RFC 822 the format of valid email
71             addresses is defined. This check routine is somewhat better than
72             I, the only disadvantage is, that some working email addresses
73             don't follow the RFC 822 standard. So if you have problems try using
74             the I routine.
75              
76             Thanks to Richard Piacentini for fixing this method :)
77              
78             It now simply uses the rfc822 method of Email::Valid (you have to
79             install Email::Valid to be able to use this method).
80              
81             =cut
82              
83             ######################################################################
84              
85             sub _check_rfc822 {
86             my($value) = @_;
87             return '' unless($value ne '');
88             require Email::Valid;
89             return gettext('standard incompatible') unless
90             Email::Valid->rfc822($value);
91             return '';
92             }
93              
94             ######################################################################
95              
96             =head2 date
97              
98             Returns I if the field value seems to be incompatible to
99             common date formats or the date doesn't exist in the Gregorian
100             calendar. The following formats are allowed:
101              
102             dd.mm.yyyy dd-mm-yyyy dd/mm/yyyy yyyy-mm-dd yyyy/mm/dd yyyy.mm.dd
103              
104             The C method of the I package is used to
105             prove the dates existence.
106              
107             =cut
108              
109             ######################################################################
110              
111             sub _check_date {
112             my ($value) = @_;
113             return '' unless($value ne '');
114             my ($d, $m, $y);
115             my $msg = gettext('invalid').'!';
116              
117             # dd.mm.yyyy dd-mm-yyyy dd/mm/yyyy
118             if($value =~ m/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{2,4})$/ || $value =~ m/^([0-9]{2})-([0-9]{2})-([0-9]{2,4})$/ || $value =~ m/^([0-9]{2})\/([0-9]{2})\/([0-9]{2,4})$/) {
119             $d = $1;
120             $m = $2;
121             $y = $3;
122             }
123             # yyyy-mm-dd yyyy/mm/dd yyyy.mm.dd
124             elsif($value =~ m/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/ || $value =~ m/^([0-9]{4})\/([0-9]{2})\/([0-9]{2})$/ || $value =~ m/^([0-9]{4}).([0-9]{2}).([0-9]{2})$/) {
125             $d = $3;
126             $m = $2;
127             $y = $1;
128             }
129             else {
130             return $msg;
131             }
132              
133             if(! check_date($y, $m, $d)) {
134             return $msg;
135             }
136              
137             return '';
138             }
139              
140             ######################################################################
141              
142             =head2 digitonly
143              
144             ... returns I if the value doesn't match C<[0-9]*>.
145              
146             =cut
147              
148             ######################################################################
149              
150             sub _check_digitonly {
151             ($_,$self,$caller,$min,$max) = @_;
152             return '' unless($_ ne '');
153             $regex = '^[0-9]{' . ($min||0) . ',' . ($max||'') . '}' . '$';
154             return gettext('invalid').'!' unless(m/$regex/);
155             return '';
156             }
157              
158             ######################################################################
159              
160             =head2 match
161              
162             Expects a variable name as first argument. If the argument is not
163             given, the method uses I as variable name. It then trys to
164             read in the value of the variable and returns an error if its not
165             equal to the value of the current field.
166              
167             This method can also compare arrays. In that case the two arrays must
168             have the same count of fields and every field must match its partner
169             in the other array.
170              
171             Please also read L.
172              
173             =head2 fmatch
174              
175             Like C but instead of expecting the argument to be a variable
176             name it expects it to be a fieldname and thus compares the currents
177             field value with the value of the field which fieldname was given. If
178             the argument is not given, the method will try to read in the variable
179             I to be compatible to older versions of FormEngine (fmatch is
180             deprecated, don't use it!). The rest works exactly as in C.
181              
182             If the value of the field that you want to check against isn't unique
183             because you used that field name several times, you can use a trick:
184             call the handler C in the fields definition so that
185             its value is saved to a global variable which by default is I
186             (that's why the C check methods default is also I). Have
187             a look at FormEngine:.DBSQL s example I
188             for better understanding.
189              
190             B When you're using the DBSQL extension and you defined several
191             tables, you must reference other fields with I!
192              
193             =cut
194              
195             ######################################################################
196              
197             sub _check_match {
198             my($value,$self,$caller,$match,$namevar) = @_;
199             if($caller eq 'fmatch') {
200             $match = $self->_get_var('fmatch') unless(defined($match) and $match ne '');
201             return '' unless($match ne '');
202             local $_ = $match;
203             $match = $self->_get_input($match);
204             if(ref($match) eq 'ARRAY' and ref($value) ne 'ARRAY') {
205             my $field = $self->_get_var($namevar||'NAME');
206             $match = $match->[$self->{values}->{$field}||0];
207             $match = $match->[$self->{_handle_error}->{$field}-1] if(ref($match) eq 'ARRAY');
208             }
209             carp("no such field: $_") and return '' unless(defined($match));
210             }
211             else {
212             $match = $self->_get_var($match||'saved');
213             }
214             return '' unless($match ne '');
215             my $errmsg = gettext('doesn\'t match') . '!';
216             if(ref($match) eq 'ARRAY' and ref($value) eq 'ARRAY') {
217             return $errmsg if(@{$match} ne @{$value});
218             for(my $i = 0; $i < @{$value}; $i++) {
219             return $errmsg if($value->[$i] ne $match->[$i]);
220             }
221             }
222             else {
223             return $errmsg if($value ne $match);
224             }
225             return '';
226             }
227              
228             ######################################################################
229              
230             =head2 regex
231              
232             Expects a regular expression string as first argument. For being
233             compatible to older versions of FormEngine it'll read in the special
234             variable I if the first argument is not given (I is
235             deprecated, don't use it!). If the value doesn't match this regex,
236             I is returned.
237              
238             =cut
239              
240             ######################################################################
241              
242             sub _check_regex {
243             my($value,$self,$caller,$regex) = @_;
244             return '' unless($value ne '');
245             $regex = $self->_get_var('regex') unless($regex);
246             if($regex) {
247             return gettext('invalid').'!' unless($value =~ m/$regex/);
248             }
249             return '';
250             }
251              
252             ######################################################################
253              
254             =head2 unique
255              
256             This check method simply checks that the fields value is unique in the
257             list of values of fields with the same field name. So this check
258             method only makes sense if you used a field name more than one
259             time. You can pass it the name of the variable which configures the
260             field name. The default is I which should be fine, so you
261             normally don't have to pass any arguments.
262              
263             It returns I if the check fails. Note: you can translate
264             this text easily so that it is displayed in the language configured by
265             your locale setting. Read I for more info.
266              
267             =cut
268              
269             ######################################################################
270              
271             sub _check_unique {
272             my($value,$self,$caller,$namevar) = @_;
273             return '' unless($value ne '');
274             my $values = $self->_get_input($self->_get_var($namevar||'NAME'));
275             return '' unless(ref($values) eq 'ARRAY');
276             $value = [$value] unless(ref($value) eq 'ARRAY');
277             local $_;
278             my $t = 0;
279             foreach $_ (@$values) {
280             $_ = [$_] unless(ref($_) eq 'ARRAY');
281             my $x = 0;
282             for(my $i = 0; $i<@$value; $i ++) {
283             $x += ($value->[$i] eq $_->[$i]) ? 1 : -1;
284             }
285             $t ++ if($x > 0);
286             return gettext('not unique').'!' if($t > 1);
287             }
288             return '';
289             }
290              
291             ######################################################################
292              
293             1;
294              
295             =head1 WRITING A CHECK ROUTINE
296              
297             =head2 Design
298              
299             In general, a check routine has the following structure:
300              
301             sub mycheck {
302             my($value,$self,$caller,@args) = @_;
303             #some lines of code#
304             return gettext('My ErrorMessage');
305             }
306              
307             C<$value> contains the submitted field value.
308              
309             C<$self> contains a reference to the FormEngine object.
310              
311             C<$caller> contains the name with which the check method was called,
312             B That means that
313             it was referenced by its name defined in by the skin. Methods
314             referenced directly by a function reference do not get passed this
315             value.
316              
317             C<@args> contains the list of arguments configured by the user for
318             that check method call.
319              
320             B you can define the error message and pass arguments by
321             yourself with the help of an array: [checkmethod, errmsg, arg1, arg2..]
322              
323             =head2 Install
324              
325             If your routine does a general job, you can make it part of a
326             FormEngine skin. Therefore just add the routine to e.g. this file and
327             refer to it from I or any other skin package. Please send me
328             such routines.
329              
330             =head1 ERROR MESSAGE TRANSLATIONS
331              
332             The translations of the error messages are stored in I
333             files. Calling I translates these into I
334             files. You must store these FormEngine.mo files in your locale
335             directory, this should be I, if it isn't, you have
336             to pass the right pass to the constructor of your FormEngine skin (see
337             L and e.g. C).
338              
339             Provided that a translation for I exists, you can call
340             C in your script to have the
341             FormEngine error message in I.
342              
343             =cut
344              
345             1;
346              
347             __END__