File Coverage

blib/lib/Data/Transpose/EmailValid.pm
Criterion Covered Total %
statement 47 48 97.9
branch 6 8 75.0
condition n/a
subroutine 11 12 91.6
pod 5 5 100.0
total 69 73 94.5


line stmt bran cond sub pod time code
1             package Data::Transpose::EmailValid;
2              
3 6     6   19604 use strict;
  6         10  
  6         212  
4 6     6   25 use warnings;
  6         11  
  6         244  
5 6     6   3643 use Email::Valid;
  6         695500  
  6         259  
6 6     6   759 use Moo;
  6         12372  
  6         50  
7             extends 'Data::Transpose::Validator::Base';
8 6     6   3530 use MooX::Types::MooseLike::Base qw(:all);
  6         7324  
  6         2586  
9 6     6   878 use namespace::clean;
  6         12606  
  6         52  
10              
11             =head1 NAME
12              
13             Data::Transpose::EmailValid - Perl extension to check if a mail is valid (with some autocorrection)
14              
15             =head1 SYNOPSIS
16              
17             use Data::Transpose::EmailValid;
18              
19             my $email = Data::Transpose::EmailValid->new;
20              
21             ok($email->is_valid("user@domain.tld"), "Mail is valid");
22              
23             ok(!$email->is_valid("user_e;@domain.tld"), "Mail is not valid");
24              
25             warn $email->reason; # output the reason of the failure
26              
27             =head1 DESCRIPTION
28              
29             This module check if the mail is valid, using the L
30             module. It also provides some additional methods.
31              
32             =head2 AUTO CORRECTION
33              
34             This validator corrects common mistakes automatically:
35              
36             =over 4
37              
38             =item
39              
40             C<.ocm> instead of C<.com> as top level domain for C,
41             C, C and C, e.g. C.
42              
43             =item
44              
45             Double dots before top level domain, e.g. C.
46              
47             =back
48              
49             Please suggest further auto correction examples to us.
50              
51             =head1 METHODS
52              
53             =head2 new
54              
55             Constructor. It doesn't accept any arguments.
56              
57             =cut
58              
59             has _email_valid => (is => 'ro',
60             isa => Object,
61             default => sub {
62             return Email::Valid->new(
63             -fudge => 1,
64             -mxcheck => 1,
65             );
66             });
67              
68             has input => (is => 'rwp',
69             isa => Maybe[Str]);
70              
71             has output => (is => 'rwp',
72             isa => Maybe[Str]);
73              
74              
75             =head2 input
76              
77             Accessor to the input email string.
78              
79             =head2 output
80              
81             Accessor to the output email string.
82              
83             =head2 reset_all
84              
85             Clear all the internal data
86              
87             =cut
88              
89              
90             sub reset_all {
91 31     31 1 58 my $self = shift;
92 31         159 $self->reset_errors;
93 31         4420 $self->_set_input(undef);
94 31         5635 $self->_set_output(undef);
95             }
96              
97             =head2 $obj->is_valid($emailstring);
98              
99             Returns the email passed if valid, false underwise.
100              
101             =cut
102              
103              
104             sub is_valid {
105 31 50   31 1 10466 return if @_ == 1;
106              
107 31         73 my ($self, $email) = @_;
108              
109             # overwrite old data
110 31         139 $self->reset_all;
111              
112 31         5131 $self->_set_input($email);
113              
114             # correct common typos # Maybe add an option for this?
115 31         4062 $email = $self->_autocorrect;
116              
117             # do validation
118 31         236 $email = $self->_email_valid->address($email);
119 31 100       940702 unless ($email) {
120 12         84 $self->error($self->_email_valid->details);
121 12         76 return;
122             }
123              
124 19         923 $self->_set_output($email);
125 19         2551 return $email;
126             }
127              
128             =head2 $obj->email
129              
130             Returns the last checked email.
131              
132             =cut
133              
134 0     0 1 0 sub email { shift->output }
135              
136             =head2 $obj->reason
137              
138             Returns the reason of the failure of the last check, false if it was
139             successful.
140              
141             =cut
142              
143              
144 6     6 1 23 sub reason { shift->error }
145              
146             =head2 $obj->suggestion
147              
148             This module implements some basic autocorrection. Calling ->suggestion
149             after a successfull test, will return the suggested value if the input
150             was different from the output, false otherwise.
151              
152             =cut
153              
154             sub suggestion {
155 8     8 1 54 my ($self) = @_;
156 8 50       56 return if $self->error;
157              
158 8 100       60 if ($self->input ne $self->output) {
159 4         14 return $self->output;
160             }
161              
162 4         10 return;
163             }
164              
165              
166             sub _autocorrect {
167 31     31   68 my $self = shift;
168 31         127 my $email = $self->input;
169             # trim
170 31         100 $email =~ s/^\s+//;
171 31         93 $email =~ s/\s+$//;
172             # .ocm -> .com
173 31         95 foreach (qw/aol gmail hotmail yahoo/) {
174 124         1553 $email =~ s/\b$_\.ocm$/$_.com/;
175             }
176             # double dots in domain part
177 31         74 $email =~ s/\.\.(\w+)$/.$1/;
178              
179             # setting the error breaks the retrocompatibility
180             # $self->error("typo?");
181 31         80 return $email;
182             }
183              
184             =head1 AUTHOR
185              
186             Uwe Voelker
187              
188             =head1 LICENSE AND COPYRIGHT
189              
190             Copyright 2012-2016 Uwe Voelker .
191              
192             This program is free software; you can redistribute it and/or modify it
193             under the terms of either: the GNU General Public License as published
194             by the Free Software Foundation; or the Artistic License.
195              
196             See http://dev.perl.org/licenses/ for more information.
197              
198             =cut
199              
200              
201             1;
202