View | Details | Raw Unified | Return to bug 17433
Collapse All | Expand All

(-)a/Koha/Validation.pm (-6 / +196 lines)
Lines 21-31 use utf8; Link Here
21
use strict;
21
use strict;
22
use warnings;
22
use warnings;
23
23
24
use C4::Context;
25
use Email::Valid;
24
use Email::Valid;
26
25
26
use C4::Context;
27
use C4::Biblio;
28
27
use vars qw($VERSION);
29
use vars qw($VERSION);
28
30
31
use Koha::Exception::BadParameter;
32
29
=head1 NAME
33
=head1 NAME
30
34
31
Koha::Validation - validates inputs
35
Koha::Validation - validates inputs
Lines 76-87 returns: 1 if the given phone number is valid, 0 otherwise. Link Here
76
sub validate_phonenumber {
80
sub validate_phonenumber {
77
    my $phonenumber = shift;
81
    my $phonenumber = shift;
78
82
83
    my $validatePhoneNumber = C4::Context->preference("ValidatePhoneNumber");
79
    # make sure we are allowed to validate phone numbers
84
    # make sure we are allowed to validate phone numbers
80
    return 1 if C4::Context->preference("ValidatePhoneNumber") eq "OFF";
85
    return 1 if $validatePhoneNumber eq "OFF";
81
    return 1 if not $phonenumber;
86
    return 1 if not $phonenumber;
82
    return 0 if $phonenumber =~ /(^(\s))|((\s)$)/;
87
    return 0 if $phonenumber =~ /(^(\s))|((\s)$)/;
83
88
84
    my $regex = get_phonenumber_regex(C4::Context->preference("ValidatePhoneNumber"));
89
    my $regex = get_phonenumber_regex($validatePhoneNumber);
85
    return ($phonenumber !~ /$regex/) ? 0:1;
90
    return ($phonenumber !~ /$regex/) ? 0:1;
86
}
91
}
87
92
Lines 99-117 returns: the regex Link Here
99
=cut
104
=cut
100
105
101
sub get_phonenumber_regex {
106
sub get_phonenumber_regex {
102
    if (C4::Context->preference("ValidatePhoneNumber") eq "ipn") {
107
    my ($validatePhoneNumber) = @_;
108
    if ($validatePhoneNumber eq "ipn") {
103
        return qr/^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$/;
109
        return qr/^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$/;
104
    }
110
    }
105
    elsif (C4::Context->preference("ValidatePhoneNumber") eq "fin") {
111
    elsif ($validatePhoneNumber eq "fin") {
106
        return qr/^((90[0-9]{3})?0|\+358([-\s])?)(?!(100|20(0|2(0|[2-3])|9[8-9])|300|600|700|708|75(00[0-3]|(1|2)\d{2}|30[0-2]|32[0-2]|75[0-2]|98[0-2])))(4|50|10[1-9]|20(1|2(1|[4-9])|[3-9])|29|30[1-9]|71|73|75(00[3-9]|30[3-9]|32[3-9]|53[3-9]|83[3-9])|2|3|5|6|8|9|1[3-9])([-\s])?(\d{1,3}[-\s]?){2,12}\d$/;
112
        return qr/^((90[0-9]{3})?0|\+358([-\s])?)(?!(100|20(0|2(0|[2-3])|9[8-9])|300|600|700|708|75(00[0-3]|(1|2)\d{2}|30[0-2]|32[0-2]|75[0-2]|98[0-2])))(4|50|10[1-9]|20(1|2(1|[4-9])|[3-9])|29|30[1-9]|71|73|75(00[3-9]|30[3-9]|32[3-9]|53[3-9]|83[3-9])|2|3|5|6|8|9|1[3-9])([-\s])?(\d{1,3}[-\s]?){2,12}\d$/;
107
    }
113
    }
108
114
109
    return qr/(.*)/;
115
    return qr/(.*)/;
110
  }
116
}
117
118
my ($f, $sf);
119
sub getMARCSubfieldSelectorCache {
120
    return $sf;
121
}
122
sub getMARCFieldSelectorCache {
123
    return $f;
124
}
125
sub getMARCSelectorCache {
126
    return {f => $f, sf => $sf};
127
}
111
128
112
129
113
=head2 use_validator
130
=head2 use_validator
114
131
132
DEPRECATED, use tries()
133
115
Validates given input with given validator.
134
Validates given input with given validator.
116
135
117
  Koha::Validation::use_validator("phone", 123456789);
136
  Koha::Validation::use_validator("phone", 123456789);
Lines 140-143 sub use_validator { Link Here
140
    return 0;
159
    return 0;
141
}
160
}
142
161
162
=HEAD2 tries
163
164
Same as use_validator except wraps exceptions as Exceptions
165
See tests in t/Koha/Validation.t for usage examples.
166
167
    my $ok = Koha::Validation->tries('key', ['koha@example.com', 'this@example.com'], 'email', 'a');
168
    try {
169
        Koha::Validation->tries('key', 'kohaexamplecom', 'email');
170
    } catch {
171
        print $_->message;
172
    };
173
174
@PARAM1 String, human readable key for the value we are validating
175
@PARAM2 Variable, variable to be validated. Can be an array or hash or a scalar
176
@PARAM3 String, validator selector, eg. email, phone, marcSubfieldSelector, ...
177
@PARAM4 String, the expected nested data types.
178
                For example 'aa' is a Array of arrays
179
                'h' is a hash
180
                'ah' is a array of hashes
181
@RETURNS 1 if everything validated ok
182
@THROWS Koha::Exception::BadParameter typically. See individual validator functions for Exception type specifics
183
184
=cut
185
186
sub tries {
187
    my ($package, $key, $val, $validator, $types) = @_;
188
189
    if ($types) {
190
        my $t = substr($types,0,1); #Get first char
191
        $package->$t($key, $val, $validator, substr($types,1)); #Trim first char from types
192
    }
193
    else {
194
        my $err = __PACKAGE__->$validator($val);
195
        Koha::Exception::BadParameter->throw(error => "'$key' '$val' $err") if $err;
196
        return 1;
197
    }
198
    return 1;
199
}
200
201
sub a {
202
    my ($package, $key, $val, $validator, $types) = @_;
203
    Koha::Exception::BadParameter->throw(error => _errmsg($key, $val, 'is not an \'ARRAY\'')) unless (ref($val) eq 'ARRAY');
204
205
    if ($types) {
206
        for (my $i=0 ; $i<@$val ; $i++) {
207
            my $v = $val->[$i];
208
            my $t = substr($types,0,1); #Get first char
209
            $package->$t($key.'->'.$i, $v, $validator, substr($types,1)); #Trim first char from types
210
        }
211
    }
212
    else {
213
        for (my $i=0 ; $i<@$val ; $i++) {
214
            my $v = $val->[$i];
215
            $package->tries($key.'->'.$i, $v, $validator, $types);
216
        }
217
    }
218
}
219
sub h {
220
    my ($package, $key, $val, $validator, $types) = @_;
221
    Koha::Exception::BadParameter->throw(error => _errmsg($key, $val, 'is not a \'HASH\'')) unless (ref($val) eq 'HASH');
222
223
    if ($types) {
224
        while(my ($k, $v) = each(%$val)) {
225
            my $t = substr($types,0,1); #Get first char
226
            $package->$t($key.'->'.$k, $v, $validator, substr($types,1)); #Trim first char from types
227
        }
228
    }
229
    else {
230
        while(my ($k, $v) = each(%$val)) {
231
            $package->tries($key.'->'.$k, $v, $validator, $types);
232
        }
233
    }
234
}
235
sub email {
236
    my ($package, $val) = @_;
237
238
    return 'is not a valid \'email\'' if (not defined Email::Valid->address($val));
239
    return undef;
240
}
241
sub double {
242
    my ($package, $val) = @_;
243
244
    return 'is not a valid \'double\'' unless ($val =~ /^\d+\.?\d*$/);
245
    return undef;
246
}
247
sub string {
248
    my ($package, $val) = @_;
249
250
    return 'is not a valid \'string\', but undefined' unless(defined($val));
251
    return 'is not a valid \'string\', but zero length' if(length($val) == 0);
252
    return 'is not a valid \'string\', but a char' if(length($val) == 1);
253
    return undef;
254
}
255
sub phone {
256
    my ($package, $val) = @_;
257
258
    my $regex = get_phonenumber_regex(C4::Context->preference("ValidatePhoneNumber"));
259
    return 'is not a valid \'phonenumber\'' if ($val !~ /$regex/);
260
    return undef;
261
}
262
263
=head2 marcSubfieldSelector
264
265
See marcSelector()
266
267
=cut
268
269
sub marcSubfieldSelector {
270
    my ($package, $val) = @_;
271
272
    if ($val =~ /^([0-9.]{3})(\w)$/) {
273
        ($f, $sf) = ($1, $2);
274
        return undef;
275
    }
276
    ($f, $sf) = (undef, undef);
277
    return 'is not a MARC subfield selector';
278
}
279
280
=head2 marcFieldSelector
281
282
See marcSelector()
283
284
=cut
285
286
sub marcFieldSelector {
287
    my ($package, $val) = @_;
288
289
    if ($val =~ /^([0-9.]{3})$/) {
290
        ($f, $sf) = ($1, undef);
291
        return undef;
292
    }
293
    ($f, $sf) = (undef, undef);
294
    return 'is not a MARC field selector';
295
}
296
297
=head2 marcSelector
298
299
Sets package variables
300
$__PACKAGE__::f    = MARC field code
301
$__PACKAGE__::sf   = MARC subfield code
302
if a correct MARC selector was found
303
for ease of access
304
The existing variables are overwritten when a new validation check is done.
305
306
Access them using getMARCSubfieldSelectorCache() and getMARCFieldSelectorCache()
307
308
marcSelector can also deal with any value in KohaToMARCMapping.
309
marcSubfieldSelector() and marcFieldSelector() deal with MARC-tags only
310
311
@PARAM1, String, current package
312
@PARAM2, String, MARC selector, eg. 856u or 110
313
314
=cut
315
316
sub marcSelector {
317
    my ($package, $val) = @_;
318
319
    if ($val =~ /^([0-9.]{3})(\w*)$/) {
320
        ($f, $sf) = ($1, $2);
321
        return undef;
322
    }
323
    ($f, $sf) = C4::Biblio::GetMarcFromKohaField($val, '');
324
    return 'is not a MARC selector' unless ($f && $sf);
325
    return undef;
326
}
327
328
sub _errmsg {
329
    my ($key, $val, $err) = @_;
330
    return "\"$key\" => \"$val\" $err";
331
}
332
143
1;
333
1;
(-)a/t/Koha/Validation.t (-1 / +197 lines)
Line 0 Link Here
0
- 
1
# Copyright 2016 KohaSuomi
2
#
3
# This file is part of Koha.
4
#
5
6
use Modern::Perl;
7
use Test::More;
8
9
use Scalar::Util qw(blessed);
10
use Try::Tiny;
11
12
use C4::Biblio;
13
use Koha::Validation;
14
15
use t::lib::TestObjects::SystemPreferenceFactory;
16
use t::lib::TestObjects::ObjectFactory;
17
18
19
my $globalContext = {};
20
my $spref = t::lib::TestObjects::SystemPreferenceFactory->createTestGroup([
21
                    {
22
                        preference => 'ValidatePhoneNumber',
23
                        value => 'fin',
24
                    },
25
                    {
26
                        preference => 'ValidateEmailAddress',
27
                        value => 1,
28
                    },
29
                    ], undef, $globalContext);
30
31
subtest "Validate email", \&simpleEmail;
32
sub simpleEmail {
33
    is(Koha::Validation::use_validator('email', 'koha@example.com'),
34
       1,
35
       "Valid email");
36
    is(Koha::Validation::use_validator('email', 'koha@examplecom'),
37
       0,
38
       "InValid email");
39
}
40
41
subtest "Validate phone", \&simplePhone;
42
sub simplePhone {
43
    is(Koha::Validation::use_validator('phone', '+358504497763'),
44
       1,
45
       "Valid phone");
46
    is(Koha::Validation::use_validator('phone', '+35504497763'),
47
       0,
48
       "InValid phone");
49
}
50
51
subtest "Validate array of something", \&arrayOf;
52
sub arrayOf {
53
    my @array = ('+358504497763', '0451123123');
54
    is(Koha::Validation->tries('phnbr', \@array, 'phone', 'a' ),
55
       1,
56
       "Valid phonenumber array");
57
58
    push(@array, 'soita heti');
59
    try {
60
        is(Koha::Validation->tries('phnbr', \@array, 'phone', 'a' ),
61
           'SHOULD THROW AN EXCEPTION!',
62
           "InValid phonenumber array");
63
    } catch {
64
        is(ref($_), 'Koha::Exception::BadParameter',
65
           "InValid phonenumber array");
66
67
        is($_->message,
68
           "'phnbr->2' 'soita heti' is not a valid 'phonenumber'",
69
           "Got a well formatted error message");
70
    };
71
}
72
73
subtest "Validate string", \&simpleString;
74
sub simpleString {
75
76
    is(Koha::Validation->tries('key', '+358504497763', 'string'),
77
       1,
78
       "Valid string");
79
80
    try {
81
        is(Koha::Validation->tries('key', 'A', 'string'),
82
           'SHOULD THROW AN EXCEPTION!',
83
           "Not a string, but a char");
84
    } catch {
85
        is(ref($_), 'Koha::Exception::BadParameter',
86
           "Not a string, but a char");
87
88
        is($_->message,
89
           "'key' 'A' is not a valid 'string', but a char",
90
           "Got a well formatted error message");
91
    };
92
93
    try {
94
        is(Koha::Validation->tries('key', '', 'string'),
95
           'SHOULD THROW AN EXCEPTION!',
96
           "Not a string, but a nothing");
97
    } catch {
98
        is(ref($_), 'Koha::Exception::BadParameter',
99
           "Not a string, but a nothing");
100
    };
101
102
    is(Koha::Validation->tries('key', 'AB', 'string'),
103
       1,
104
       "Valid short String");
105
}
106
107
subtest "Array of Array of doubles", \&nestedArrayDoubles;
108
sub nestedArrayDoubles {
109
110
    my @array = ([0.4, 1.2],
111
                 [4.5, 7.9]);
112
    is(Koha::Validation->tries('nay', \@array, 'double', 'aa'),
113
       1,
114
       "Valid nested array of doubles");
115
116
    push(@array, [2, 'lol']);
117
    try {
118
        is(Koha::Validation->tries('nay', \@array, 'double', 'aa'),
119
           'SHOULD THROW AN EXCEPTION!',
120
           "InValid nested array of doubles");
121
    } catch {
122
        is(ref($_), 'Koha::Exception::BadParameter',
123
           "InValid nested array of doubles");
124
125
        is($_->message,
126
           "'nay->2->1' 'lol' is not a valid 'double'",
127
           "Got a well formatted error message");
128
    };
129
}
130
131
subtest "MARC Selectors", \&marcSelectors;
132
sub marcSelectors {
133
134
    is(Koha::Validation->tries('mrc', '856', 'marcFieldSelector',),
135
       1,
136
       "Valid MARC Field selector");
137
    is(Koha::Validation::getMARCFieldSelectorCache, '856', "Validated MARC Field remembered");
138
    is(Koha::Validation::getMARCSubfieldSelectorCache, undef, "Not touched MARC Subfield not defined");
139
140
    try {
141
        is(Koha::Validation->tries('mrc', '85u', 'marcFieldSelector',),
142
           'SHOULD THROW AN EXCEPTION!',
143
           "InValid MARC Field selector");
144
    } catch {
145
        is(ref($_), 'Koha::Exception::BadParameter',
146
           "InValid MARC Field selector");
147
148
        is($_->message,
149
           "'mrc' '85u' is not a MARC field selector",
150
           "Got a well formatted error message");
151
    };
152
    is(Koha::Validation::getMARCFieldSelectorCache,  undef, "InValidated MARC Field forgot");
153
    is(Koha::Validation::getMARCSubfieldSelectorCache, undef, "Not touched MARC Subfield not defined");
154
155
    is(Koha::Validation->tries('mrc', '110a', 'marcSubfieldSelector',),
156
       1,
157
       "Valid MARC Subfield selector");
158
    is(Koha::Validation::getMARCFieldSelectorCache,  '110', "Validated MARC Field remembered");
159
    is(Koha::Validation::getMARCSubfieldSelectorCache, 'a',   "Validated MARC Subfield remembered");
160
161
    try {
162
        is(Koha::Validation->tries('mrc', '110', 'marcSubfieldSelector',),
163
           'SHOULD THROW AN EXCEPTION!',
164
           "InValid MARC Subfield selector");
165
    } catch {
166
        is(ref($_), 'Koha::Exception::BadParameter',
167
           "InValid MARC Subfield selector");
168
169
        is($_->message,
170
           "'mrc' '110' is not a MARC subfield selector",
171
           "Got a well formatted error message");
172
    };
173
    is(Koha::Validation::getMARCFieldSelectorCache,  undef, "InValidated MARC Field forgot");
174
    is(Koha::Validation::getMARCSubfieldSelectorCache, undef, "InValidated MARC Subfield forgot");
175
176
    is(Koha::Validation->tries('mrc', '110a', 'marcSelector',),
177
       1,
178
       "Valid MARC selector");
179
    is(Koha::Validation::getMARCFieldSelectorCache,  '110', "Validated MARC Field remembered");
180
    is(Koha::Validation::getMARCSubfieldSelectorCache, 'a',   "Validated MARC Subfield remembered");
181
182
    is(Koha::Validation->tries('mrc', '245', 'marcSelector',),
183
       1,
184
       "Valid MARC selector");
185
    is(Koha::Validation::getMARCFieldSelectorCache, '245',  "Validated MARC Field remembered");
186
    is(Koha::Validation::getMARCSubfieldSelectorCache, '', "Not given MARC Subfield forgot");
187
188
    my ($f, $sf) = C4::Biblio::GetMarcFromKohaField('biblio.title', '');
189
    is(Koha::Validation->tries('mrc', 'biblio.title', 'marcSelector'),
190
       1,
191
       "biblio.title is a valid MARC Selector");
192
    is(Koha::Validation::getMARCFieldSelectorCache,    $f,  "Field from KohaToMarcMapping");
193
    is(Koha::Validation::getMARCSubfieldSelectorCache, $sf, "Subfield from KohaToMarcMapping");
194
}
195
196
t::lib::TestObjects::ObjectFactory->tearDownTestContext($globalContext);
197
done_testing();

Return to bug 17433