Андрей (andy) wrote in changelog,
Андрей
andy
changelog

[livejournal] r21825: LJSUP-11976 (refactor methods working wi...

Committer: ailyin
LJSUP-11976 (refactor methods working with infohistory into classes of its own)
U   trunk/cgi-bin/LJ/Console/Command/ChangeCommunityAdmin.pm
U   trunk/cgi-bin/LJ/Console/Command/ChangeJournalType.pm
U   trunk/cgi-bin/LJ/Console/Command/Infohistory.pm
U   trunk/cgi-bin/LJ/Console/Command/ResetEmail.pm
U   trunk/cgi-bin/LJ/Console/Command/ResetPassword.pm
U   trunk/cgi-bin/LJ/Event/SecurityAttributeChanged.pm
U   trunk/cgi-bin/LJ/Poll.pm
U   trunk/cgi-bin/LJ/User/EmailStatus.pm
A   trunk/cgi-bin/LJ/User/InfoHistory.pm
A   trunk/cgi-bin/LJ/User/InfoHistoryRecord.pm
U   trunk/cgi-bin/LJ/User/Rename.pm
U   trunk/cgi-bin/LJ/User.pm
U   trunk/htdocs/changeemail.bml
U   trunk/htdocs/changepassword.bml
U   trunk/htdocs/manage/profile/index.bml
U   trunk/t/console-infohistory.t
U   trunk/t/console-reset.t
Modified: trunk/cgi-bin/LJ/Console/Command/ChangeCommunityAdmin.pm
===================================================================
--- trunk/cgi-bin/LJ/Console/Command/ChangeCommunityAdmin.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Console/Command/ChangeCommunityAdmin.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -46,8 +46,7 @@
     LJ::set_rel($ucomm, $unew, 'A');
 
     # so old maintainers can't regain access
-    my $dbh = LJ::get_db_writer();
-    $dbh->do("DELETE FROM infohistory WHERE userid = ?", undef, $ucomm->id);
+    LJ::User::InfoHistory->clear($ucomm);
 
     # change password to blank and set email of community to new maintainer's email
     LJ::update_user($ucomm, { password => '', email => $unew->email_raw });

Modified: trunk/cgi-bin/LJ/Console/Command/ChangeJournalType.pm
===================================================================
--- trunk/cgi-bin/LJ/Console/Command/ChangeJournalType.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Console/Command/ChangeJournalType.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -141,17 +141,26 @@
         $extra{password} = $ou->password;
     }
 
-    LJ::infohistory_add($u, 'password', Digest::MD5::md5_hex($u->password . 'change'))
-        if $extra{password} ne $u->password;
+    if ( $extra{password} ne $u->password ) {
+        LJ::User::InfoHistory->add( $u,
+            'password', Digest::MD5::md5_hex( $u->password . 'change' ) );
+    }
 
     # reset the email address
     $extra{email} = $ou->email_raw;
     $extra{status} = 'A';
+
+    # TODO: move this to LJ::User::InfoHistory or change it to adding a new
+    # entry; updating table with log data is not a good idea
     $dbh->do("UPDATE infohistory SET what='emailreset' WHERE userid=? AND what='email'", undef, $u->id)
         or $self->error("Error updating infohistory for emailreset: " . $dbh->errstr);
-    LJ::infohistory_add($u, 'emailreset', $u->email_raw, $u->email_status)
-        unless $ou->email_raw eq $u->email_raw; # record only if it changed
 
+    # record only if it changed
+    if ( $ou->email_raw ne $u->email_raw ) {
+        LJ::User::InfoHistory->add( $u,
+            'emailreset', $u->email_raw, $u->email_status );
+    }
+
     # get the new journaltype
     $extra{journaltype} = $typemap->{$type};
 

Modified: trunk/cgi-bin/LJ/Console/Command/Infohistory.pm
===================================================================
--- trunk/cgi-bin/LJ/Console/Command/Infohistory.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Console/Command/Infohistory.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -30,20 +30,22 @@
     return $self->error("Invalid user $user")
         unless $u;
 
-    my $dbh = LJ::get_db_reader();
-    my $sth = $dbh->prepare("SELECT * FROM infohistory WHERE userid=?");
-    $sth->execute($u->id);
+    my $infohistory = LJ::User::InfoHistory->get($u);
 
     return $self->error("No matches.")
-        unless $sth->rows;
+        unless @$infohistory;
 
     $self->info("Infohistory of user: $user");
-    while (my $info = $sth->fetchrow_hashref) {
-        $info->{'oldvalue'} ||= '(none)';
-        $self->info("Changed $info->{'what'} at $info->{'timechange'}.");
-        $self->info("Old value of $info->{'what'} was $info->{'oldvalue'}.");
-        $self->info("Other information recorded: $info->{'other'}")
-            if $info->{'other'};
+    foreach my $record (@$infohistory) {
+        my $oldvalue = $record->oldvalue || '(none)';
+
+        $self->info( "Changed " . $record->what .
+            " at " . $record->timechange . "." );
+        $self->info("Old value of " . $record->what . " was $oldvalue.");
+
+        if ( my $other = $record->other ) {
+            $self->info("Other information recorded: $other");
+        }
     }
 
     return 1;

Modified: trunk/cgi-bin/LJ/Console/Command/ResetEmail.pm
===================================================================
--- trunk/cgi-bin/LJ/Console/Command/ResetEmail.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Console/Command/ResetEmail.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -33,8 +33,10 @@
 
     my $aa = LJ::register_authaction($u->id, "validateemail", $newemail);
 
-    LJ::infohistory_add($u, 'emailreset', $u->email_raw, $u->email_status)
-        if $u->email_raw ne $newemail;
+    if ( $u->email_raw ne $newemail ) {
+        LJ::User::InfoHistory->add( $u,
+            'emailreset', $u->email_raw, $u->email_status );
+    }
 
     LJ::update_user($u, { email => $newemail, status => 'T' })
         or return $self->error("Unable to set new email address for $username");
@@ -51,6 +53,8 @@
         'body' => $body,
     }) or $self->info("Confirmation email could not be sent.");
 
+    # TODO: move this to LJ::User::InfoHistory or change it to adding a new
+    # entry; updating table with log data is not a good idea
     my $dbh = LJ::get_db_writer();
     $dbh->do("UPDATE infohistory SET what='emailreset' WHERE userid=? AND what='email'",
              undef, $u->id) or return $self->error("Database error: " . $dbh->errstr);

Modified: trunk/cgi-bin/LJ/Console/Command/ResetPassword.pm
===================================================================
--- trunk/cgi-bin/LJ/Console/Command/ResetPassword.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Console/Command/ResetPassword.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -34,9 +34,7 @@
 
     my $newpass = LJ::rand_chars(8);
     my $oldpass = Digest::MD5::md5_hex($u->password . "change");
-    my $rval = LJ::infohistory_add($u, 'passwordreset', $oldpass);
-    return $self->error("Failed to insert old password into infohistory.")
-        unless $rval;
+    LJ::User::InfoHistory->add( $u, 'passwordreset', $oldpass );
 
     LJ::update_user($u, { password => $newpass, })
         or return $self->error("Failed to set new password for $username");

Modified: trunk/cgi-bin/LJ/Event/SecurityAttributeChanged.pm
===================================================================
--- trunk/cgi-bin/LJ/Event/SecurityAttributeChanged.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Event/SecurityAttributeChanged.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -58,35 +58,22 @@
         # TODO: check is $u a user object?
         die "Missing credentials" unless $ip && $action && $old_username;
 
-        my $dbh = LJ::get_db_writer($u);
-        my $sth = $dbh->prepare(
-            "SELECT UNIX_TIMESTAMP(timechange) as utimechange, oldvalue".
-            " FROM infohistory".
-            " WHERE userid=? AND what='username'".
-            " ORDER BY utimechange DESC LIMIT 2");
-        $sth->execute($userid);
-        my ($timechange, $oldvalue) = $sth->fetchrow_array;
+        my $infohistory = LJ::User::InfoHistory->get( $u, 'username' );
+        my ($latest_record) =
+            reverse
+            sort { $a->timechange_unix <=> $b->timechange_unix }
+            @$infohistory;
 
-        # Check for errors
         die "This event (uid=$userid, what=username) was not found in logs"
-            unless $timechange;
+            unless $latest_record;
 
+        my $timechange = $latest_record->timechange_unix;
+        my $oldvalue   = $latest_record->oldvalue;
+
         die "Event (uid=$userid, what=username) was not found in logs".
             " has wrong old username: $oldvalue instead of $old_username"
                 if $oldvalue ne $old_username;
 
-        my ($timechange2, $oldvalue2) = $sth->fetchrow_array;
-        die "Second record about this event was found in log"
-            if $timechange2 && $timechange2 == $timechange && ($oldvalue2 ne $oldvalue);
-
-        # Remember ip address
-        $dbh->do(
-            "UPDATE infohistory".
-            " SET other='ip=$ip'".
-            " WHERE userid=$userid".
-            "   AND what='username'".
-            "   AND UNIX_TIMESTAMP(timechange)=$timechange");
-
         return $timechange;
     };
 
@@ -201,20 +188,19 @@
         my ($u, $timechange_stamp) = @_;
         my $userid = $u->{userid};
 
-        my $dbh = LJ::get_db_reader($u);
-        my $sth = $dbh->prepare(
-            "SELECT oldvalue, other".
-            " FROM infohistory".
-            " WHERE userid=? AND what='username' AND UNIX_TIMESTAMP(timechange)=?");
-        $sth->execute($userid, $timechange_stamp);
-        my ($old_name, $other) = $sth->fetchrow_array;
+        my $infohistory = LJ::InfoHistory->get( $u, 'username' );
+        my ($infohistory_record) =
+            grep { $_->timechange_unix == $timechange_stamp }
+            @$infohistory;
 
-        # Check for errors
-        unless ($old_name) {
+        unless ($infohistory_record) {
             croak "This event (uid=$userid, what=username) was not found in logs";
             return undef;
         }
 
+        my $old_name = $infohistory_record->oldvalue;
+        my $other    = $infohistory_record->other;
+
         # Convert $timechange from GMT to local for user
         my $offset = 0;
         LJ::get_timezone($u, \$offset);

Modified: trunk/cgi-bin/LJ/Poll.pm
===================================================================
--- trunk/cgi-bin/LJ/Poll.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/Poll.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -2127,20 +2127,10 @@
             }
 
             if (@$uids) {
-                my $remote_email = $remote->email_raw;
                 my $us = LJ::load_userids(@$uids);
 
                 # Get all emails for the user submitting the poll
-                my $dbr = LJ::get_db_reader();
-                my $sth = $dbr->prepare("SELECT oldvalue FROM infohistory " .
-                                        "WHERE userid=? AND what='email' " .
-                                        "ORDER BY timechange");
-                $sth->execute($remote->{'userid'});
-                my @emails;
-                push @emails, $remote_email;
-                while (my $em = $sth->fetchrow_array) {
-                    push @emails, $em;
-                }
+                my @emails = map { $_->{'email'} } @{ $remote->emails_info };
 
                 foreach my $u (values %$us) {
                     next unless $u;

Modified: trunk/cgi-bin/LJ/User/EmailStatus.pm
===================================================================
--- trunk/cgi-bin/LJ/User/EmailStatus.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/User/EmailStatus.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -142,7 +142,8 @@
         my $new_status = $is_disabled ? 'T' : 'A';
         
         LJ::update_user($user, { 'status' => $new_status } );
-        LJ::infohistory_add($user->userid, 'email_status', $old_status, $user->email_raw);
+        LJ::User::InfoHistory->add( $user,
+            'email_status', $old_status, $user->email_raw );
     }
 }
 

Added: trunk/cgi-bin/LJ/User/InfoHistory.pm
===================================================================
--- trunk/cgi-bin/LJ/User/InfoHistory.pm	                        (rev 0)
+++ trunk/cgi-bin/LJ/User/InfoHistory.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -0,0 +1,66 @@
+package LJ::User::InfoHistory;
+use strict;
+use warnings;
+
+use LJ::User::InfoHistoryRecord;
+
+sub add {
+    my ( $class, $u, $what, $oldvalue, $other ) = @_;
+
+    my $dbh = LJ::get_db_writer();
+    local $dbh->{'RaiseError'} = 1;
+
+    $dbh->do(
+        'INSERT INTO infohistory ' .
+        'SET userid=?, what=?, timechange=NOW(), oldvalue=?, other=?',
+        undef,
+        $u->userid, $what, $oldvalue, $other,
+    );
+
+    $LJ::REQ_GLOBAL{'infohistory_cache'} ||= {};
+    delete $LJ::REQ_GLOBAL{'infohistory_cache'}->{ $u->userid };
+
+}
+
+sub get {
+    my ( $class, $u, $what ) = @_;
+
+    $LJ::REQ_GLOBAL{'infohistory_cache'} ||= {};
+    unless ( exists $LJ::REQ_GLOBAL{'infohistory_cache'}->{ $u->userid } ) {
+        my $dbr = LJ::get_db_reader();
+        local $dbr->{'RaiseError'} = 1;
+
+        my $rows = $dbr->selectall_arrayref(
+            'SELECT * FROM infohistory WHERE userid=? ORDER BY timechange',
+            { 'Slice' => {} },
+            $u->userid,
+        );
+
+        $LJ::REQ_GLOBAL{'infohistory_cache'}->{ $u->userid } =
+            [ map { LJ::User::InfoHistoryRecord->new($_) } @$rows ];
+    }
+
+    my $records = $LJ::REQ_GLOBAL{'infohistory_cache'}->{ $u->userid };
+    return $records unless $what;
+
+    if ( ref $what eq 'ARRAY' ) {
+        my %acceptable_what = map { $_ => 1 } @$what;
+        return [ grep { $acceptable_what{ $_->what } } @$records;
+    } else {
+        return [ grep { $_->what eq $what } @$records ];
+    }
+}
+
+sub clear {
+    my ( $class, $u ) = @_;
+
+    my $dbh = LJ::get_db_writer();
+    local $dbh->{'RaiseError'} = 1;
+
+    $dbh->do( 'DELETE FROM infohistory WHERE userid=?', undef, $u->userid );
+
+    $LJ::REQ_GLOBAL{'infohistory_cache'} ||= {};
+    $LJ::REQ_GLOBAL{'infohistory_cache'}->{ $u->userid } = [];
+}
+
+1;

Added: trunk/cgi-bin/LJ/User/InfoHistoryRecord.pm
===================================================================
--- trunk/cgi-bin/LJ/User/InfoHistoryRecord.pm	                        (rev 0)
+++ trunk/cgi-bin/LJ/User/InfoHistoryRecord.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -0,0 +1,23 @@
+package LJ::User::InfoHistoryRecord;
+use strict;
+use warnings;
+
+use base qw( Class::Accessor );
+__PACKAGE__->mk_ro_accessors( qw( userid what timechange oldvalue other ) );
+
+sub new {
+    my ( $class, $row ) = @_;
+    return bless { %$row }, $class;
+}
+
+sub user {
+    my ($self) = @_;
+    return LJ::load_userid( $self->userid );
+}
+
+sub timechange_unix {
+    my ($self) = @_;
+    return LJ::TimeUtil->mysqldate_to_time( $self->timechange );
+}
+
+1;

Modified: trunk/cgi-bin/LJ/User/Rename.pm
===================================================================
--- trunk/cgi-bin/LJ/User/Rename.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/User/Rename.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -165,8 +165,11 @@
     $dbh->do("DELETE FROM expunged_users WHERE user IN (?, ?)",
              undef, $from, $to);
 
-    LJ::infohistory_add($u, 'username', $from);
+    my $ip = $opts->{'ip'};
+    $ip ||= LJ::is_web_context() ? LJ::Request->remote_ip() : '127.0.0.1';
 
+    LJ::User::InfoHistory->add( $u, 'username', $from, "ip=$ip" );
+
     # tell all web machines to clear their caches for this userid/name mapping
     LJ::procnotify_add("rename_user", { 'userid' => $u->{'userid'},
                                         'user' => $u->{'user'} });
@@ -194,7 +197,7 @@
         LJ::Event::SecurityAttributeChanged->new($u ,  { 
             action       => 'account_renamed', 
             old_username => $from, 
-            ip           => ($opts->{ip} || (LJ::is_web_context() ? LJ::Request->remote_ip() : '127.0.0.1')),
+            ip           => $ip,
             datetime     => sprintf("%02d:%02d %02d/%02d/%04d", @date[2,1], $date[3], $date[4]+1, $date[5]+1900),
         })->fire;
     }

Modified: trunk/cgi-bin/LJ/User.pm
===================================================================
--- trunk/cgi-bin/LJ/User.pm	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/cgi-bin/LJ/User.pm	2012-04-27 11:15:14 UTC (rev 21825)
@@ -10,44 +10,50 @@
 #             so the queries can be tagged for use by the star replication
 #             daemon.
 
+package LJ::User;
 use strict;
 no warnings 'uninitialized';
 
-package LJ::User;
-use Carp;
 use lib "$ENV{LJHOME}/cgi-bin";
-use List::Util ();
-use LJ::Request;
+
+use Carp;
+use HTTP::Date qw( str2time );
+use List::Util qw();
+use URI        qw();
+
 use LJ::Constants;
+use LJ::JSON;
+use LJ::FileStore;
 use LJ::MemCache;
+use LJ::RateLimit           qw();
+use LJ::RelationService;
+use LJ::Request;
 use LJ::Session;
-use LJ::RateLimit qw//;
-use URI qw//;
-use LJ::JSON;
-use HTTP::Date qw(str2time);
 use LJ::TimeUtil;
+use LJ::User::InfoHistory;
 use LJ::User::PropStorage;
-use LJ::FileStore;
-use LJ::RelationService;
 
+# TODO: get rid of Class::Autouse, maybe? it's pretty useless
+# in web context and leads to some nasty bugs otherwise, so probably
+# the benefit is not worth it
 use Class::Autouse qw(
-                      URI
-                      LJ::Subscription
-                      LJ::SMS
-                      LJ::SMS::Message
-                      LJ::Identity
-                      LJ::Auth
-                      LJ::Jabber::Presence
-                      LJ::S2
-                      IO::Socket::INET
-                      Time::Local
-                      LJ::M::FriendsOf
-                      LJ::BetaFeatures
-                      LJ::S2Theme
-                      LJ::Subscription
-                      LJ::Subscription::GroupSet
-                      );
+    IO::Socket::INET
+    Time::Local
 
+    LJ::Auth
+    LJ::BetaFeatures
+    LJ::Identity
+    LJ::Jabber::Presence
+    LJ::M::FriendsOf
+    LJ::Subscription
+    LJ::S2
+    LJ::S2Theme
+    LJ::SMS
+    LJ::SMS::Message
+    LJ::Subscription
+    LJ::Subscription::GroupSet
+);
+
 # class method to create a new account.
 sub create {
     my ($class, %opts) = @_;
@@ -2335,16 +2341,11 @@
 sub last_password_change_time {
     my ($u) = @_;
 
-    my $dbr = LJ::get_db_reader();
-    my ($time) = $dbr->selectrow_array(
-        'SELECT UNIX_TIMESTAMP(MAX(timechange)) FROM infohistory ' .
-        'WHERE userid=? AND what="password"',
-        undef,
-        $u->userid,
-    );
+    my $infohistory = LJ::User::InfoHistory->get( $u, 'password' );
+    my @password_change_timestamps = map { $_->timechange_unix } @$infohistory;
 
-    $time ||= 0;
-    return $time;
+    return 0 unless @password_change_timestamps;
+    return List::Util::max( @password_change_timestamps );
 }
 
 # THIS IS DEPRECATED DO NOT USE
@@ -2466,20 +2467,6 @@
     return 1;
 }
 
-# this is DEPRECATED in favor of can_reset_password_using_email
-sub can_receive_password {
-    my ($u, $email) = @_;
-
-    return 0 unless $u && $email;
-    return 1 if lc($email) eq lc($u->email_raw);
-
-    my $dbh = LJ::get_db_reader();
-    return $dbh->selectrow_array("SELECT COUNT(*) FROM infohistory ".
-                                 "WHERE userid=? AND what='email' ".
-                                 "AND oldvalue=? AND other='A'",
-                                 undef, $u->id, $email);
-}
-
 # my $u = LJ::want_user(12);
 # my $data = $u->get_email_data('test@test.ru');
 # print $data->{'email_state'}; # email status if test@test.ru is the
@@ -2523,23 +2510,31 @@
 
     my @ret;
 
-    my $dbr = LJ::get_db_reader();
-    my $infohistory_rows = $dbr->selectall_arrayref(
-        'SELECT what, UNIX_TIMESTAMP(timechange) AS timechange, '.
-        'oldvalue, other FROM infohistory WHERE userid=? AND '.
-        'what IN ("email", "emaildeleted") ORDER BY timechange',
-        { Slice => {} }, $u->id
-    );
-    my @infohistory_rows = @$infohistory_rows;
+    my $infohistory =
+        LJ::User::InfoHistory->get( $u, [ 'email', 'emaildeleted' ] );
 
-    # this actually finds the greatest timechange in rows before $rownum;
+    my $infohistory_records =
+        [ sort { $a->timechange_unix <=> $b->timechange_unix } @$infohistory ];
+
+    # my $dbr = LJ::get_db_reader();
+    # my $infohistory_rows = $dbr->selectall_arrayref(
+    #     'SELECT what, UNIX_TIMESTAMP(timechange) AS timechange, '.
+    #     'oldvalue, other FROM infohistory WHERE userid=? AND '.
+    #     'what IN ("email", "emaildeleted") ORDER BY timechange',
+    #     { Slice => {} }, $u->id
+    # );
+    # my @infohistory_rows = @$infohistory_rows;
+
+    # this actually finds the greatest timechange in rows before $recordnum;
     # if it fails to find it, it returns $u->timecreate
     my $find_timeset = sub {
-        my ($rownum) = @_;
+        my ($recordnum) = @_;
 
-        for (my $rownum2 = $rownum-1; $rownum2 >= 0; $rownum2--) {
-            my $row2 = $infohistory_rows->[$rownum2];
-            return $row2->{'timechange'} if ($row2->{'what'} eq 'email');
+        for ( my $recordnum2 = $recordnum - 1;
+            $recordnum2 >= 0; $recordnum2-- )
+        {
+            my $record2 = $infohistory_records->[$recordnum2];
+            return $record2->timechange_unix if $record2->what eq 'email';
         }
 
         # in case we found nothing, the address was set when the account
@@ -2547,23 +2542,18 @@
         return $u->timecreate;
     };
 
-    foreach my $rownum (0..$#infohistory_rows) {
-        my $row = $infohistory_rows->[$rownum];
-        if ($row->{'what'} eq 'email') {
+    foreach my $recordnum ( 0 .. $#$infohistory_records ) {
+        my $record = $infohistory_records->[$recordnum];
+        if ( $record->what eq 'email' ) {
             # new email has been added to the list, but now, we're going to
             # record the old address
-
-            my $email = { email => $row->{'oldvalue'} };
-            $email->{'changed'} = $row->{'timechange'};
-            $email->{'status'} = $row->{'other'};
-
-            # in case we found nothing, the address was set when the account
-            # was registered
-
-            $email->{'set'} = $find_timeset->($rownum);
-
-            push @ret, $email;
-        } elsif ($row->{'what'} eq 'emaildeleted') {
+            push @ret, {
+                'email'   => $record->oldvalue,
+                'changed' => $record->timechange_unix,
+                'status'  => $record->other,
+                'set'     => $find_timeset->($recordnum),
+            };
+        } elsif ( $record->what eq 'emaildeleted' ) {
             # there may be two cases here: 1) it was something like an admin
             # deletion or 2) it was deletion through /tools/emailmanage.bml,
             # which previously did 'UPDATE infohistory SET what="emaildelete"'
@@ -2571,57 +2561,59 @@
             # /tools/emailmanage.bml has since been changed to record that
             # change as a new entry, which returns us to the first case
 
-            unless ($row->{'other'} =~ /;/) {
+            unless ( $record->other =~ /;/ ) {
                 # first case: find all other occurences of that email
                 # and mark them with the date of deletion
 
                 foreach my $email (@ret) {
-                    next unless $email->{'email'} eq $row->{'oldvalue'};
-                    next unless $email->{'set'} <= $row->{'timechange'};
+                    next unless $email->{'email'} eq $record->oldvalue;
+                    next unless $email->{'set'} <= $record->timechange_unix;
 
-                    $email->{'deleted'} = $row->{'timechange'}
+                    $email->{'deleted'} = $record->timechange_unix
                         unless $email->{'deleted'};
                 }
             } else {
                 # second case: parse the timestamp, create an email hashref,
-                # find the row with the next address to set "set", and
+                # find the record with the next address to set "set", and
                 # finally, mark it as deleted. ugh.
 
-                my ($status, $time) = split /;/, $row->{'other'};
+                my ( $status, $time ) = split /;/, $record->other;
 
                 # there is no joke here. in infohistory, time is stored as
                 # MySQL DATETIME. emailmanage.bml used to just append it to
                 # previous status, so now, we need to parse.
                 $time = str2time($time);
 
-                my $email = { email => $row->{'oldvalue'} };
-                $email->{'changed'} = $time;
-                $email->{'status'} = $status;
-                $email->{'deleted'} = $row->{'timechange'};
+                # we need to find the first record which has timestamp
+                # greater or equal to $time so that we can call $find_timeset
+                my $nextrecord = 0;
+                foreach my $recordnum2 ( 0 .. $#$infohistory_records ) {
+                    my $record2 = $infohistory_records->[$recordnum2];
+                    next unless $record2->what eq 'email';
+                    next if $record2->timechange_unix < $time;
 
-                # now, we need to find the first row which has timestamp more
-                # or equal to $time so that we can call $find_timeset
-                my $nextrow = 0;
-                foreach my $rownum2 (0..$#infohistory_rows) {
-                    my $row2 = $infohistory_rows->[$rownum2];
-                    next unless $row2->{'what'} eq 'email';
-                    next if $row2->{'timechange'} < $time;
-
-                    $nextrow = $rownum2;
+                    $nextrecord = $recordnum2;
                     last;
                 }
 
-                $email->{'set'} = $find_timeset->($nextrow);
-                push @ret, $email;
+                push @ret, {
+                    'email'   => $record->oldvalue,
+                    'changed' => $time,
+                    'status'  => $status,
+                    'deleted' => $record->timechange_unix,
+                    'set'     => $find_timeset->($nextrecord),
+                };
             }
         }
     }
 
     # finally, the current address
-    my $email = { email => $u->email_raw, current => 1 };
-    $email->{'status'} = $u->email_status;
-    $email->{'set'} = $find_timeset->($#infohistory_rows + 1);
-    push @ret, $email;
+    push @ret, {
+        'email'   => $u->email_raw,
+        'current' => 1,
+        'status'  => $u->email_status,
+        'set'     => $find_timeset->( $#$infohistory_records + 1 ),
+    };
 
     $u->{'_emails'} = \@ret;
     return \@ret;
@@ -2762,15 +2754,9 @@
 
     return unless $u->can_delete_email($addr);
 
-    my $dbh = LJ::get_db_writer();
-    $dbh->do(
-        'INSERT INTO infohistory SET '.
-        'userid=?, what="emaildeleted", timechange=NOW(), '.
-        'oldvalue=?', undef, $u->id, $addr
-    );
+    LJ::User::InfoHistory->add( $u, 'emaildeleted', $addr );
 
     # update cache now
-
     my $emails = $u->emails_info;
     foreach my $email (@$emails) {
         next if $email->{'deleted'};
@@ -6046,7 +6032,7 @@
 
     LJ::memcache_kill($u, "userid");
 
-    LJ::infohistory_add($u, 'identity', $from);
+    LJ::User::InfoHistory->add( $u, 'identity', $from );
 
     return 1;
 }
@@ -7694,29 +7680,6 @@
 }
 
 # <LJFUNC>
-# name: LJ::infohistory_add
-# des: Add a line of text to the [[dbtable[infohistory]] table for an account.
-# args: uuid, what, value, other?
-# des-uuid: User id or user object to insert infohistory for.
-# des-what: What type of history is being inserted (15 chars max).
-# des-value: Value for the item (255 chars max).
-# des-other: Optional. Extra information / notes (30 chars max).
-# returns: 1 on success, 0 on error.
-# </LJFUNC>
-sub infohistory_add {
-    my ($uuid, $what, $value, $other) = @_;
-    $uuid = LJ::want_userid($uuid);
-    return unless $uuid && $what && $value;
-
-    # get writer and insert
-    my $dbh = LJ::get_db_writer();
-    my $gmt_now = LJ::TimeUtil->mysql_time(time(), 1);
-    $dbh->do("INSERT INTO infohistory (userid, what, timechange, oldvalue, other) VALUES (?, ?, ?, ?, ?)",
-             undef, $uuid, $what, $gmt_now, $value, $other);
-    return $dbh->err ? 0 : 1;
-}
-
-# <LJFUNC>
 # name: LJ::get_shared_journals
 # des: Gets an array of shared journals a user has access to.
 # returns: An array of shared journals.

Modified: trunk/htdocs/changeemail.bml
===================================================================
--- trunk/htdocs/changeemail.bml	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/htdocs/changeemail.bml	2012-04-27 11:15:14 UTC (rev 21825)
@@ -125,7 +125,8 @@
 
         LJ::statushistory_add($u->{userid}, $u->{userid}, 'email_changed', $loginfo);
 
-        LJ::infohistory_add($u, 'email', $old_email, $u->{status});
+        LJ::User::InfoHistory->add( $u,
+            'email', $old_email, $u->email_status );
 
         $u->log_event('email_change', { remote => $remote, new => $POST{'email'} });
 

Modified: trunk/htdocs/changepassword.bml
===================================================================
--- trunk/htdocs/changepassword.bml	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/htdocs/changepassword.bml	2012-04-27 11:15:14 UTC (rev 21825)
@@ -44,7 +44,7 @@
 
      # verify the email can still receive passwords
      return LJ::bad_input(BML::ml('.error.emailchanged', { 'aopts' => "href='$LJ::SITEROOT/lostinfo.bml'"}))
-         unless $authu->can_receive_password($aa->{arg1});
+         unless $authu->can_reset_password_using_email( $aa->{'arg1'} );
  }
 
  my $update_form = sub {
@@ -178,7 +178,7 @@
      ## make note of changed password
      my $dbh = LJ::get_db_writer();
      my $oldval = Digest::MD5::md5_hex($u->password . "change");
-     LJ::infohistory_add($u, 'password', $oldval);
+     LJ::User::InfoHistory->add( $u, 'password', $oldval );
 
      $u->log_event('password_change', { remote => $remote });
 

Modified: trunk/htdocs/manage/profile/index.bml
===================================================================
--- trunk/htdocs/manage/profile/index.bml	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/htdocs/manage/profile/index.bml	2012-04-27 11:15:14 UTC (rev 21825)
@@ -854,7 +854,8 @@
         my $email_changed = (($u->email_raw ne $POST{'email'}) && !$LJ::EMAIL_CHANGE_REQUIRES_PASSWORD);
         if ($email_changed) {
             # record old email address;
-            LJ::infohistory_add($u, 'email', $u->email_raw, $u->{status});
+            LJ::User::InfoHistory->add( $u,
+                'email', $u->email_raw, $u->email_status );
 
             $u->log_event('email_change', { remote => $remote, new => $POST{'email'} });
 

Modified: trunk/t/console-infohistory.t
===================================================================
--- trunk/t/console-infohistory.t	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/t/console-infohistory.t	2012-04-27 11:15:14 UTC (rev 21825)
@@ -24,7 +24,7 @@
    "error: No matches.");
 
 # put something in there.
-LJ::infohistory_add($u2, 'email', $u2->email_raw, 'T');
+LJ::User::InfoHistory->add( $u2, 'email', $u2->email_raw, 'T' );
 
 my $response = $run->("infohistory " . $u2->user);
 like($response, qr/Changed email at \d{4}-\d{2}-\d{2}/, "Date recorded correctly.");

Modified: trunk/t/console-reset.t
===================================================================
--- trunk/t/console-reset.t	2012-04-27 09:14:53 UTC (rev 21824)
+++ trunk/t/console-reset.t	2012-04-27 11:15:14 UTC (rev 21825)
@@ -31,8 +31,8 @@
 is($u2->email_status, "T", "Email status set correctly.");
 
 my $dbh = LJ::get_db_reader();
-my $rv = $dbh->do("SELECT * FROM infohistory WHERE userid=? AND what='email'", undef, $u2->id);
-ok($rv < 1, "Addresses wiped from infohistory.");
+my $infohistory = LJ::User::InfoHistory->get( $u2, 'email' );
+ok( @$infohistory < 1, "Addresses wiped from infohistory." );
 
 $u->revoke_priv("reset_email");
 

Tags: ailyin, andy, bml, livejournal, pm, t
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments