File Coverage

blib/lib/Database/Schema/Verification.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Database::Schema::Verification;
2              
3 1     1   19674 use 5.008007;
  1         5  
  1         40  
4 1     1   6 use strict;
  1         2  
  1         32  
5 1     1   5 use warnings;
  1         5  
  1         38  
6 1     1   1186 use MIME::Lite;
  1         38911  
  1         32  
7 1     1   697 use Class::ParmList qw(parse_parms);
  1         1306  
  1         51  
8 1     1   352 use Time::Timestamp;
  0            
  0            
9              
10             our $VERSION = '1.02';
11             use constant TABLE => 'verification';
12             use constant HARD_RETURN_LIMIT => 500; # hard coded hashref return limit, can be overridden locally
13              
14             =head1 NAME
15              
16             Database::Schema::Verification - Perl extension for storing and verifing various levels of information
17              
18             =head1 SYNOPSIS
19              
20             use Database::Schema::Verification;
21              
22             my $v = Database::Schema::Verification->new(
23             -dbh => $dbh,
24             -type => 'my_type',
25             -type_id => 22,
26             -msg => $txtVerificationEmailMsg,
27             );
28              
29             my $rv = $v->check();
30             my $rv = $v->insert();
31             my $rv = $v->isVerified();
32             my $rv = $v->load();
33             my $rv = $v->requestVerification();
34             my $rv = $v->verifiy(-action => 1);
35             my $rv = $v->remove();
36              
37             # returns array of Database::Schema::Verification objects
38             # each of a hardcoded return limit of 500, wich can be overwritten
39             my @ary = $v->returnUnprocessed();
40             my @ary = $v->returnUnverified();
41            
42              
43             =head1 DESCRIPTION
44              
45             The Verification module provides an easy storage interface for keeping track of what data has been verified, what has been surpressed and what needs verification. At it's core it provides a relation between it's master key (vid) and a combination of the type of data you are working with (usually associates with a table within your database) and it's master key. This module also provides you with a simple email tool that provides notification of an event requiring verification.
46              
47             Accompanied within this is a 'contrib' directory. In there you'll find a CGI script. The purpose of this script is to allow authors the ability to place embedded links within the email notifications. These links can provide a set of parameters that will trigger any of the verification functions. This allows users to click the links in the email and verify or surpess data as it becomes avalible.
48              
49             The basic concept is to allow authors to insert this where ever they need to. This can be it's own verification database where:
50              
51             type => 'databaseName.table',
52             type_id => $databaseName.table.keyId
53              
54             This would allow you to maintain one verification database for multiple databases or applications
55              
56             OR it can be a simple table embeded into your program database
57              
58             type => 'table',
59             type_id => $table.keyId
60              
61             This allows you to scale it as you need it and apply verification to any level of data you are working with.
62              
63             **Note: All string returns are in the format:
64              
65             return ('reason we bombed out...',[undef,0]);
66              
67             This allows you to extract why the function failed with a:
68              
69             my ($str,$rv) = function->check(...);
70             if(!defined($rv)){
71             die($str);
72             }
73              
74             =head1 OBJECT METHODS
75              
76             =head2 new()
77              
78             Default constructor
79              
80             my $v = Database::Schema::Verification->new(
81             # required
82             -dbh => $dbh,
83             -type => 'my_type',
84             -type_id => 22,
85             -msg => $txtVerificationEmailMsg,
86              
87             # optional
88             -vid => $vid,
89             -dt_added => $dt_added, [see Time::Timestamp]
90             -dt_updated => $dt_updated, [see Time::Timestamp]
91             -verified => $verified, # see verified() for inputs
92             -verified_by => $verified_by,
93             -verified_by_ip => $verified_by_ip, [see Net::IP]
94             -table => $table # default is 'verification'
95             );
96              
97             =over 4
98              
99             =item dbh [DBI handle]
100              
101             A DBI handle
102              
103             =item vid [int]
104              
105             This pre-specifies the verification id
106              
107             =item type [string]
108              
109             This is the type of data we are verifiying (usually use the database table we are targeting)
110              
111             =item type_id [int]
112              
113             The key id field for the table data we are verifing
114              
115             =item msg [string]
116              
117             Text to be included in the verification message
118              
119             =item dt_added [int|string] (stored as Time::Timestamp obj)
120              
121             Optional: Initial timestamp, automagically inserted if left blank
122              
123             =item dt_updated [int|string] (stored as Time::Timestamp obj)
124              
125             Optional: Last updated timestamp, automagically handled if left blank
126              
127             =item verified [int]
128              
129             Optional: Allows you to auto set the verification status (see verify() for list of inputs
130              
131             =item verified_by [string]
132              
133             Optional: Allows specification of the verifing source (who done did it)
134              
135             =item verified_by_ip [string|int] (stores as Net::IP object)
136              
137             Optional: Allows specification of the source ip who verified the data (who's box done did it)
138              
139             =item table [string]
140              
141             Option: Overrides the default base table definition # default is 'verification'
142              
143             =back
144              
145             =cut
146             sub new {
147             my ($class,%parms) = @_;
148             my $self = {};
149             bless($self,$class);
150             $self->init(%parms);
151             return $self;
152             }
153              
154             # INIT
155              
156             sub init {
157             my ($self,%parms) = @_;
158             $parms{-table} = TABLE() if(!$parms{-table});
159             $parms{-ignoreTypeCase} = 1 if(!$parms{-ignoreTypeCase});
160              
161             die 'We need a dbh!!' if(!$parms{-dbh});
162             $self->dbh( $parms{-dbh});
163             $self->table( $parms{-table});
164             $self->vid( $parms{-vid});
165             $self->type_id( $parms{-type_id});
166             $self->type( $parms{-type});
167             $self->dt_added( $parms{-dt_added});
168             $self->dt_updated( $parms{-dt_updated});
169             $self->verified( $parms{-verified});
170             $self->verified_by( $parms{-verified_by});
171             $self->verified_by_ip( $parms{-verified_by_ip});
172             $self->msg( $parms{-msg});
173             }
174              
175             # METHODS
176              
177             =head2 check()
178              
179             This function checks to see if your key or key pair (type && type_id) already exist in the database. By default $v->vid(), $v->type() and $v->type_id() are taken in the function but can be overwritten with parms.
180              
181             $v->check(
182             # optional override of object properties
183             -type => $type,
184             -type_id => $type_id,
185             -vid => $vid,
186             );
187              
188             Returns:
189              
190             Errstr on failure
191             1 on KeyExsits
192             0 on keyNotExists
193              
194             =cut
195              
196             sub check {
197             my $self = shift;
198              
199             my $parms = parse_parms({
200             -parms => \@_,
201             -required => [],
202             -legal => [ qw(-type -type_id -vid) ],
203             -defaults => {
204             -type => $self->type(),
205             -type_id => $self->type_id(),
206             -vid => $self->vid(),
207             }
208             });
209              
210             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
211             my ($type,$type_id,$vid) = $parms->get('-type','-type_id','-vid');
212             return ("invalid params: [type,type_id|vid] required! \n",undef) unless(($type && $type_id) || $vid);
213              
214             my ($sql,@x);
215             if($vid){
216             $sql = 'SELECT id FROM `'.$self->table().'` WHERE `id` = ?';
217             $x[0] = $vid;
218             }
219             else {
220             $sql = 'SELECT id FROM `'.$self->table().'` WHERE `type_id` = ? and `type` = ?';
221             @x = ($type_id,$type);
222             }
223              
224             my $sth = $self->dbh->prepare($sql);
225             my $rv = $sth->execute(@x);
226             if($rv) {
227             my @row = $sth->fetchrow_array();
228             return (undef,1) if($row[0]);
229             return 0;
230             }
231             return ('database failed: '.$self->dbh->errstr(),undef);
232             }
233              
234             =head2 insert()
235              
236             This function loads a verification object into the database (pre-checks the type && type_id first). By default $v->vid(),$v->type() and $v->type_id() are checked. These can be overwritten with params.
237              
238             $v->insert(
239             # optional override of object properties
240             -type => $type,
241             -type_id => $type_id,
242             -fork => 1, # forks back a loaded object on insert completion
243              
244             # vid can be set manually, but it's usually auto-incremented by the database
245             # all other properties should be set by the new() or their accessors before this is called
246             );
247              
248             Returns:
249              
250             0 on KeyExists
251             $objectRef [-forkOnExists]
252             Errstr on failure
253             ($vid,1) on success
254             ($objectRef,1) on success [with fork parm]
255              
256             =cut
257              
258             sub insert {
259             my $self = shift;
260              
261             my $parms = parse_parms({
262             -parms => \@_,
263             -required => [qw(-type -type_id)],
264             -legal => [qw(-type -type_id -vid -fork -forkOnExist -msg )],
265             -defaults => {
266             -type => $self->type(),
267             -type_id => $self->type_id(),
268             -vid => $self->vid(),
269             -msg => $self->msg(),
270             }
271             });
272             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
273             my ($vid,$type,$type_id,$fork,$forkOnExist,$msg) = $parms->get('-vid','-type','-type_id','-fork','-forkOnExist','-msg');
274              
275             $self->dt_added(time()) unless($self->dt_added());
276             $self->dt_updated(time());
277              
278             if($self->check(-type => $type, -type_id => $type_id, -vid => $vid) == 1){
279             return ('check: keys already exist',0) unless($forkOnExist);
280             return (undef,$self->load(-vid => $vid, -type => $type, -type_id => $type_id, -fork => 1));
281             }
282              
283             my $sql = 'INSERT INTO `'.$self->table().'` (`id`,`type_id`,`type`,`dt_added`,`dt_updated`,`msg`) VALUES (?,?,?,?,?,?)';
284             my $sth = $self->dbh->prepare($sql);
285             my $rv = $sth->execute($vid,$type_id,$type,$self->dt_added->epoch(),$self->dt_updated->epoch(),$msg);
286             return ('insert failed: '.$self->dbh->errstr(),undef) unless($rv);
287              
288             return ($self->returnVid(),1) unless($fork);
289             return (undef,$self->load(-type=> $type, -type_id => $type_id, -fork => 1));
290             }
291              
292             =head2 requestVerification()
293              
294             Function takes in MIME::Lite parms and submits a notification for review. It can become particularly useful when coupled with a cgi script (see contrib directory). Embedding links into these messages allows you to verify or suppress verification by clicking a link in the email.
295              
296             my $msg = 'Please Verify Me!!!!';
297             $v->requestVerification(
298             -to => 'myself@you.com',
299             -from => 'root@localhost',
300             -msg => $msg,
301             -subject => 'Verification required!!',
302              
303             # optional
304             -update => 1, # default
305             );
306              
307             Returns:
308              
309             Errstr on failure
310             1 on success
311              
312             =over 4
313              
314             =item update
315              
316             By default, a call to requestVerification() will update our 'verified' status in the table to 0 (notified, but unverified). If for some reason we need to suppress it, setting -update => 0 (NOT UNDEF!) will do override it for us.
317              
318             =item debug
319              
320             This will print the email to screen will cause our database to NOT be updated (no matter what).
321              
322             $v-requestVerification(
323             ...,
324             ...,
325             -debug => 1,
326             );
327              
328             =back
329              
330             Supported Email Args:
331              
332             -to,-from,-cc,-bcc,-subject,-type,-msg
333              
334             See MIME::Lite for more info
335              
336             Returns:
337              
338             Errstr on failure
339             1 on success
340              
341             =cut
342              
343             sub requestVerification {
344             my $self = shift;
345              
346             my $parms = parse_parms({
347             -parms => \@_,
348             -required => [ qw(-to -from -subject -msg) ],
349             -defaults => {
350             -msg => $self->msg(),
351             -cc => '',
352             -bcc => '',
353             -update => 1,
354             }
355             });
356              
357             return "invalid parameters\n".Carp::longmess (Class::ParmList->error()) unless(defined($parms));
358              
359             my ($to,$from,$cc,$bcc,$subject,$type,$msg,$update,$debug) = $parms->get('-to','-from','-cc','-bcc','-subject','-type','-msg','-update','-debug');
360             my $email = MIME::Lite->new(
361             From => $from,
362             To => $to,
363             Cc => $cc,
364             Bcc => $bcc,
365             Subject => $subject,
366             Type => $type,
367             Data => $msg,
368             );
369             return (print $email->as_string()."\n") if($debug);
370             my $rv = $email->send();
371             if($rv){
372             return (undef,1) unless($update);
373             $self->verify(-action => 0);
374             }
375             return ('msg failed to send: '.$rv,undef);
376             }
377              
378             =head2 isVerified()
379              
380             Method checks to see the verified status of the VID or keypair (type && type_id).
381              
382             my $rv = $v->isVerified(
383             # optional override of object properties
384             -type => $type,
385             -type_id => $type_id,
386             -vid => $vid,
387             );
388              
389             Returns:
390              
391             Errstr on failure
392             verified status on success (see verifiy() for more details)
393              
394             =cut
395              
396             sub isVerified {
397             my $self = shift;
398              
399             my $parms = parse_parms({
400             -parms => \@_,
401             -required => [],
402             -legal => [ qw(-type -type_id -vid) ],
403             -defaults => {
404             -type => $self->type(),
405             -type_id => $self->type_id(),
406             -vid => $self->vid(),
407             }
408             });
409              
410             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
411             my ($type,$type_id,$vid) = $parms->get('-type','-type_id','-vid');
412             return ("invalid params: [type,type_id|vid] required!\n",undef) unless(($type && $type_id) || $vid);
413              
414             return ("check failed\n",undef) if($self->check(-type => $type, -type_id => $type_id, -vid => $vid) != 1);
415              
416             my ($sql,@x);
417             if($vid) {
418             $sql = 'SELECT `verified`, `verified_by` FROM `'.$self->table().'` WHERE id = ?';
419             @x = ($vid);
420             }
421             else {
422             $sql = 'SELECT `verified`, `verified_by` FROM `'.$self->table().'` WHERE type_id = ? AND type = ?';
423             @x = ($type_id,$type);
424             }
425              
426             my $sth = $self->dbh->prepare($sql);
427             my $rv = $sth->execute(@x);
428             return ('isVerified Failed: '.$self->dbh->errstr(),undef) unless($rv);
429              
430             my @row = $sth->fetchrow_array();
431             return ($row[0]);
432             }
433              
434             =head2 returnVid()
435              
436             Returns the vid for a given pair of (type && type_id) assuming $v->vid() is not set.
437              
438             my $vid = $v->returnVid(
439             # optional override of object properties
440             -type => $type,
441             -type_id => $type_id,
442             );
443              
444             Returns:
445              
446             Errstr on failure
447             vid on succeess
448              
449             =cut
450              
451             sub returnVid {
452             my $self = shift;
453              
454             my $parms = parse_parms({
455             -parms => \@_,
456             -required => [ qw(-type -type_id) ],
457             -defaults => {
458             -type => $self->type(),
459             -type_id => $self->type_id(),
460             }
461             });
462             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
463             my ($type,$type_id) = $parms->get('-type','-type_id');
464            
465             my $sql = 'SELECT id FROM `'.$self->table().'` WHERE `type` = ? and `type_id` = ?';
466             my $sth = $self->dbh->prepare($sql);
467             my $rv = $sth->execute($type,$type_id);
468             my @row = $sth->fetchrow_array();
469             return $row[0] if($row[0]);
470             return ('no vid found',undef);
471             }
472              
473             =head2 load()
474              
475             Loads a verification record into our object or returns a fully loaded forked object.
476              
477             $v->load(
478             # optional override of object properties
479             -type => $type,
480             -type_id => $type_id,
481             );
482              
483             my $newObject = $v->load(
484             # optional override of object properties
485             -vid => $vid,
486             -fork => 1,
487             );
488              
489             Returns:
490              
491             Errstr on failure
492             1 on success and not forked
493             New Object if forked
494              
495             =cut
496              
497             sub load {
498             my $self = shift;
499              
500             my $parms = parse_parms({
501             -parms => \@_,
502             -legal => [qw(-type -type_id -vid -fork)],
503             -defaults => {
504             -type => $self->type(),
505             -type_id => $self->type_id(),
506             -vid => $self->vid(),
507             }
508             });
509             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
510             my ($type,$type_id,$vid,$fork) = $parms->get('-type','-type_id','-vid','-fork');
511             return ("invalid params: [-type,-type_id|-vid] required!\n",undef) unless($vid || ($type && $type_id));
512              
513             my $sql = 'SELECT * FROM `'.$self->table().'` WHERE ';
514             my @x;
515              
516             if($vid){ $sql .= '`id` = ?'; $x[0] = $vid; }
517             else { $sql .= '`type` = ? AND `type_id` = ?'; $x[0] = $type; $x[1] = $type_id; }
518              
519             my $sth = $self->dbh->prepare($sql);
520             my $rv = $sth->execute(@x);
521             return ('load failed: '.$self->dbh->errstr(),undef) unless($rv);
522              
523             my $hr = $sth->fetchrow_hashref();
524             return ('no records found',undef) unless(keys %$hr);
525              
526             return ref($self)->new(
527             -dbh => $self->dbh,
528             -vid => $hr->{id},
529             -msg => $hr->{msg},
530             -dt_added => $hr->{dt_added},
531             -dt_updated => $hr->{dt_updated},
532             -type => $hr->{type},
533             -type_id => $hr->{type_id},
534             -verified => $hr->{verified},
535             -id => $hr->{id},
536             -verified_by => $hr->{verified_by},
537             -verified_by_ip => $hr->{verified_by_ip},
538             ) if($fork);
539              
540             $self->vid( $hr->{id});
541             $self->type_id( $hr->{type_id});
542             $self->type( $hr->{type});
543             $self->verified( $hr->{verified});
544             $self->dt_added( $hr->{dt_added});
545             $self->dt_updated( $hr->{dt_updated});
546             $self->verified_by( $hr->{verified_by});
547             $self->verified_by_ip( $hr->{verified_by_ip});
548             $self->msg( $hr->{msg});
549             return (undef,1);
550             }
551              
552             =head2 verify()
553              
554             Sets the verification status of the object.
555              
556             $v->verify(
557             # required
558             -action => $action,
559              
560             # optional override of object properties
561             -type => $type,
562             -type_id => $type_id,
563             -vid => $vid,
564             -verified_by => $verified_by,
565             -verified_by_ip => $vip,
566             );
567              
568             =cut
569              
570             # action hashref
571             my $ACTIONS = {
572             'UNVERIFIED' => 0, # unverified but notification has been sent
573             'VERIFY' => 1, # duh
574             'SUPPRESS' => 2, # its what jcmurphy likes to call a 'false positive'
575             'UNDEFINE' => 3, # reset so the notification can be triggered again
576             'REMOVE' => 4, # get rid of the evidence
577             };
578              
579             =pod
580              
581             Actions [and or status]:
582              
583             0 - UNVERIFIED # unverified but notification has been sent [set status to 'wait']
584             1 - VERIFY # duh
585             2 - SUPPRESS # its what jcmurphy likes to call a 'false positive'
586             3 - UNDEFINE # reset so the notification can be triggered again
587             4 - REMOVE # get rid of the evidence
588              
589             Actions can be sent as strings or ints, it will figure out which automagically.
590              
591             Returns:
592              
593             Errstr on failure
594             1 on success
595              
596             =cut
597              
598             sub verify {
599             my $self = shift;
600              
601             my $parms = parse_parms({
602             -parms => \@_,
603             -required => [qw(-verified_by -action)],
604             -legal => [qw(-type -type_id -vid -verified_by -action -verified_by_ip)],
605             -defaults => {
606             -type => $self->type(),
607             -type_id => $self->type_id(),
608             -vid => $self->vid(),
609             -verified_by => $self->verified_by(),
610             -verified_by_ip => $self->verified_by_ip(),
611             }
612             });
613             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
614             my ($vid,$type,$type_id,$verified_by,$action,$verified_by_ip) = $parms->get('-vid','-type','-type_id','-verified_by','-action','-verified_by_ip');
615             return ("missing parmaeters\n",undef) unless(($vid) || ($type && $type_id));
616              
617             return ('check failed',undef) if(!$self->check(-type => $type, -type_id => $type_id, -vid => $vid));
618             my $status = $self->isVerified();
619             return ('already processed',undef) if(defined($status) && $status > 0);
620             my $a = $action;
621             $action = $ACTIONS->{uc($action)} if(!($action =~ /^\d+$/)); # change to int if they sent a string
622            
623             return ('invalid action: '.uc($a),undef) unless(defined($action) && $action =~ /^[0-3]$/);
624             return $self->remove() if($action == 4);
625             $action = undef if($action == 3);
626              
627             my @x; $x[0] = $action; $x[1] = $verified_by; $x[2] = time();
628             my $sql = 'UPDATE `'.$self->table().'` SET `verified` = ?, `verified_by` = ?, `dt_updated` = ?';
629              
630             if($self->verified_by_ip){
631             $sql .= ', verified_by_ip = '.$self->dbh->quote($self->verified_by_ip->intip());
632             }
633              
634             if($vid){
635             $sql .= ' WHERE id = ?';
636             $x[3] = $vid;
637             }
638             else{
639             $sql .= ' WHERE type_id = ? AND type = ?';
640             $x[3] = $type_id; $x[4] = $type;
641             }
642              
643             my $sth = $self->dbh->prepare($sql);
644             my $rv = $sth->execute(@x);
645             return (undef,1) if($rv);
646             return ('Verification failed: '.$self->dbh->errstr(),undef);
647             }
648              
649             =head2 remove()
650              
651             Removes the record from our table that this object represents.
652              
653             $v->remove(
654             # optional override of object properties
655             -vid => $vid,
656             -type => $type,
657             -type_id => $type_id,
658             );
659              
660             Returns:
661              
662             Errstr on failure
663             1 on success
664              
665             =cut
666              
667             sub remove {
668             my $self = shift;
669              
670             my $parms = parse_parms({
671             -parms => \@_,
672             -defaults => {
673             -vid => $self->vid(),
674             -type => $self->type(),
675             -type_id => $self->type_id(),
676             }
677             });
678             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
679             my ($vid,$type,$type_id) = $parms->get('-vid','-type','-type_id');
680             return ('missing required parameters: [vid || type && type_id]',undef) unless($vid || ($type && $type_id));
681              
682             my ($sql,@x);
683              
684             if($vid) {
685             $sql = 'DELETE FROM `'.$self->table().'` WHERE `id` = ?';
686             $x[0] = $vid;
687             }
688             else {
689             $sql = 'DELETE FROM `'.$self->table().'` WHERE `type` = ? AND `type_id` = ?';
690             $x[0] = $type;
691             $x[1] = $type_id;
692             }
693              
694             my $sth = $self->dbh->prepare($sql);
695             my $rv = $sth->execute(@x);
696              
697             return (undef,1) unless(!$rv);
698             return ('remove failed: '.$self->dbh->errstr(),undef);
699             }
700              
701             =head2 returnUnverified()
702              
703             By default this method returns an array of unverified objects from the database. Optionally a parm can override this and force the function to return a raw hashref too. There is a HARD_RETURN_LIMIT on the number of keys that can be accessed. This can also be overridden.
704              
705             my @aryOfObjects = $v->returnUnverified(
706             # optional overrides
707             -type => $type
708             );
709              
710             my $hashref = $v->returnUnverified(
711             -limit => 1000,
712             -hashref => 1,
713             );
714              
715             =over 4
716              
717             =item limit
718              
719             This will override the hard coded limit of 500. Setting -limit => 0 will return ALL records (use with caution on large databases). Because of this, if the hard limit is set, the query will return the data in desc order.
720              
721             =item hashref
722              
723             This will return a raw hashref instead of an array of objects (set to 1).
724              
725             =back
726              
727             Returns:
728              
729             Errstr on failure
730             HASHREF or OBJECT on success
731              
732             =cut
733              
734             sub returnUnverified {
735             my $self = shift;
736              
737             my $parms = parse_parms({
738             -parms =>\@_,
739             -legal => [qw(-type -limit -hashref)],
740             -defaults => {
741             -type => $self->type(),
742             -limit => HARD_RETURN_LIMIT(),
743             }
744             });
745             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
746             my ($type,$limit,$hashref) = $parms->get('-type','-limit','-hashref');
747              
748             my $sql = 'SELECT * FROM `'.$self->table().'` WHERE verified = 0';
749             $sql .= ' AND type = '.$self->dbh->quote($type) if($type);
750             $sql .= ' ORDER BY id DESC';
751             $sql .= ' LIMIT '.$limit if($limit != 0);
752              
753             my $sth = $self->dbh->prepare($sql);
754             my $rv = $sth->execute();
755              
756             return ('QueryFailed: '.$self->dbh->errstr(),undef) unless($rv);
757              
758             my $hr = $sth->fetchall_hashref('id');
759             return $hr if($hashref);
760              
761             my @a;
762             foreach my $x (keys %$hr){
763             push(@a,ref($self)->new(
764             -dbh => $self->dbh(),
765             -vid => $hr->{$x}->{id},
766             -msg => $hr->{$x}->{msg},
767             -dt_added => $hr->{$x}->{dt_added},
768             -dt_updated => $hr->{$x}->{dt_updated},
769             -type => $hr->{$x}->{type},
770             -type_id => $hr->{$x}->{type_id},
771             -verified => $hr->{$x}->{verified},
772             -id => $hr->{$x}->{id},
773             -verified_by => $hr->{$x}->{verified_by},
774             -verified_by_ip => $hr->{$x}->{verified_by_ip},
775             )
776             )
777             }
778             return @a;
779             }
780              
781             =head2 returnUnprocessed()
782              
783             See returnUnVerified().
784              
785             This returns anything that has verified set to NULL (ie: no notifications have been sent yet).
786              
787             =cut
788              
789             sub returnUnprocessed {
790             my $self = shift;
791              
792             my $parms = parse_parms({
793             -parms => \@_,
794             -legal => [qw(-type -limit -hashref)],
795             -defaults => {
796             -type => $self->type(),
797             -limit => HARD_RETURN_LIMIT(),
798             }
799             });
800              
801             return ("invalid parameters\n".Carp::longmess (Class::ParmList->error()),undef) unless(defined($parms));
802             my ($type,$limit,$hashref) = $parms->get('-type','-limit','-hashref');
803              
804             my $sql = 'SELECT * FROM `'.$self->table().'` WHERE verified IS NULL';
805             $sql .= ' AND type = '.$self->dbh->quote($type) if($type);
806             $sql .= ' ORDER BY id DESC';
807             $sql .= ' LIMIT '.$limit if($limit != 0);
808              
809             my $sth = $self->dbh->prepare($sql);
810             my $rv = $sth->execute();
811              
812             return ('QueryFailed: '.$self->dbh->errstr(),undef) unless($rv);
813             my $hr = $sth->fetchall_hashref('id');
814             return $hr if($hashref);
815              
816             my @a;
817             foreach my $x (keys %$hr){
818             push(@a,ref($self)->new(
819             -dbh => $self->dbh(),
820             -vid => $hr->{$x}->{id},
821             -msg => $hr->{$x}->{msg},
822             -dt_added => $hr->{$x}->{dt_added},
823             -dt_updated => $hr->{$x}->{dt_updated},
824             -type => $hr->{$x}->{type},
825             -type_id => $hr->{$x}->{type_id},
826             -verified => $hr->{$x}->{verified},
827             -id => $hr->{$x}->{id},
828             -verified_by => $hr->{$x}->{verified_by},
829             -verified_by_ip => $hr->{$x}->{verified_by_ip},
830             )
831             )
832             }
833             return @a;
834             }
835              
836             =pod
837              
838             =head1 OBJECT ACCESSORS and MODIFIERS
839              
840             =head2 dbh()
841              
842             Sets and Retrieves dbh handle
843              
844             =cut
845              
846             sub dbh {
847             my ($self,$v) = @_;
848             $self->{_dbh} = $v if(defined($v));
849             return $self->{_dbh};
850             }
851              
852             =head2 table()
853              
854             Sets and Retrieves the default table to use in our lookups
855              
856             =cut
857              
858             sub table {
859             my ($self,$v) = @_;
860             $self->{_table} = $v if(defined($v));
861             return $self->{_table};
862             }
863              
864             =head2 vid()
865              
866             Sets and Retrieves the Verification ID
867              
868             =cut
869              
870             sub vid {
871             my ($self,$v) = @_;
872             $self->{_vid} = $v if(defined($v));
873             return $self->{_vid};
874             }
875              
876             =head2 type()
877              
878             Sets and Retrieves the type of data we are working with (usually the other table name).
879              
880             =cut
881              
882             sub type {
883             my ($self,$v) = @_;
884             $self->{_type} = $v if(defined($v));
885             return $self->{_type};
886             }
887              
888              
889             =head2 type_id()
890              
891             Sets and Retrieves the key id for the type of data we are working with (the key in the other table).
892              
893             =cut
894              
895             sub type_id {
896             my ($self,$v) = @_;
897             $self->{_type_id} = $v if(defined($v));
898             return $self->{_type_id};
899             }
900              
901             =head2 verified()
902              
903             Sets and Retrieves the objects verification status
904              
905             =cut
906              
907             sub verified {
908             my ($self,$v) = @_;
909             $self->{_verified} = $v if(defined($v));
910             return $self->{_verified};
911             }
912              
913             =head2 dt_added()
914              
915             Sets and Retrieves the date our vid was added. Returns a Time::Timestamp object
916              
917             =cut
918              
919             sub dt_added {
920             my ($self,$v) = @_;
921             $self->{_dt_added} = Time::Timestamp->new(ts => $v) if(defined($v));
922             return $self->{_dt_added};
923             }
924              
925             =head2 dt_updated()
926              
927             Sets and Retrieves the date our vid was last updated. Returns a Time::Timestamp object
928              
929             =cut
930              
931             sub dt_updated {
932             my ($self,$v) = @_;
933             $self->{_dt_updated} = Time::Timestamp->new(ts => $v) if(defined($v));
934             return $self->{_dt_updated};
935             }
936              
937             =head2 verified_by()
938              
939             Sets and Retrieves who last set our verified field
940              
941             =cut
942              
943             sub verified_by {
944             my ($self,$v) = @_;
945             $self->{_verified_by} = $v if(defined($v));
946             return $self->{_verified_by};
947             }
948              
949             =head2 verified_by_ip()
950              
951             Sets and Retrieves what ip was used to set our last verified field. Returns a Net::IP object. Accepts Big::Int's.
952              
953             =cut
954              
955             sub verified_by_ip {
956             my ($self,$v) = @_;
957             if($v){
958             $v = Net::IP::bintoip(Net::IP::inttobin($v)) if($v =~ /^\d+$/);
959             $self->{_verified_by_ip} = Net::IP->new($v);
960             }
961             return $self->{_verified_by_ip};
962             }
963              
964             =head2 msg()
965              
966             Sets and Retrieves an optional msg that explains what needs verifying (ie: the body used to be sent in a $self->requestVerification() email.
967              
968             =cut
969              
970             sub msg {
971             my ($self,$v) = @_;
972             $self->{_msg} = $v if(defined($v));
973             return $self->{_msg};
974             }
975              
976             1;
977             __END__