diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index c680fb82c..aff596b0c 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -15,6 +15,7 @@ - fixed #10449: Undefined template - fixed #10365: Head tags do not work "Use Packed Head Tags". - fixed #9927: Survey - verbatim + - fixed #10352: Deleting a user does not clean up any address books 7.7.8 - fixed: Basic Auth doesn't work if password contains colon (Arjan Widlak, diff --git a/docs/upgrades/upgrade_7.7.8-7.7.9.pl b/docs/upgrades/upgrade_7.7.8-7.7.9.pl index c51fc0710..2fd26f437 100644 --- a/docs/upgrades/upgrade_7.7.8-7.7.9.pl +++ b/docs/upgrades/upgrade_7.7.8-7.7.9.pl @@ -22,6 +22,7 @@ use Getopt::Long; use WebGUI::Session; use WebGUI::Storage; use WebGUI::Asset; +use WebGUI::Shop::AddressBook; my $toVersion = '7.7.9'; @@ -32,6 +33,7 @@ my $session = start(); # this line required # upgrade functions go here repackTemplates( $session ); +deleteUnattachedAddressBooks( $session ); finish($session); # this line required @@ -86,6 +88,21 @@ sub repackTemplates { print "\n\t... DONE!\n" unless $quiet; } +#---------------------------------------------------------------------------- +# Delete all AddressBooks where the userId does not exist in the users table +sub deleteUnattachedAddressBooks { + my $session = shift; + + print "\n\t\tDelete all AddressBooks if the user for that book was deleted..." unless $quiet; + my $sth = $session->db->read( "SELECT addressBookId FROM addressBook where userId NOT IN (SELECT userId FROM users)" ); + while ( my ($addressBookId) = $sth->array ) { + my $book = WebGUI::Shop::AddressBook->new($session, $addressBookId); + $book->delete; + } + + print "\n\t... DONE!\n" unless $quiet; +} + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index fc789273d..fe37376eb 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -22,7 +22,9 @@ use WebGUI::Exception; use WebGUI::Utility; use WebGUI::Operation::Shared; use WebGUI::Workflow::Instance; +use WebGUI::Shop::AddressBook; use JSON; +use WebGUI::Exception; =head1 NAME @@ -352,15 +354,16 @@ sub dateCreated { Deletes this user, removes their user profile data, cleans up their inbox, removes userSessionScratch data and authentication information, removes them from any groups they belong to and deletes their -Friend's group. +Friend's group. Also deletes any address books and addresses that +belong to this user. =cut sub delete { - my $self = shift; - my $userId = $self->userId; + my $self = shift; + my $userId = $self->userId; my $session = $self->session; - my $db = $session->db; + my $db = $session->db; $self->uncache; foreach my $groupId ( @{ $self->getGroups } ) { @@ -394,6 +397,16 @@ sub delete { # remove inbox entries $db->write("DELETE FROM inbox WHERE userId=? AND (groupId IS NULL OR groupId='')",[$userId]); + # Shop cleanups + my $sth = $session->db->prepare('select addressBookId from addressBook where userId=?'); + $sth->execute([$userId]); + BOOK: while (my $bookId = $sth->hashRef) { + my $book; + eval { $book = WebGUI::Shop::AddressBook->new($session, $bookId->{addressBookId}); }; + next BOOK if (my $e = Exception::Class->caught); + $book->delete; + } + # remove user itself $db->write("DELETE FROM userProfileData WHERE userId=?",[$userId]); $db->write("DELETE FROM users WHERE userId=?",[$userId]); diff --git a/t/User.t b/t/User.t index 4003a01ef..462d27a1e 100644 --- a/t/User.t +++ b/t/User.t @@ -16,11 +16,13 @@ use WebGUI::Test; use WebGUI::Session; use WebGUI::Utility; use WebGUI::Cache; +#use Exception::Class; use WebGUI::User; use WebGUI::ProfileField; +use WebGUI::Shop::AddressBook; -use Test::More tests => 221; # increment this value for each test you create +use Test::More tests => 223; # increment this value for each test you create use Test::Deep; use Data::Dumper; @@ -241,7 +243,7 @@ cmp_ok(abs($user->lastUpdated-$lastUpdate), '<=', 1, 'lastUpdated() -- profileFi is($user->profileField('notAProfileField'), undef, 'getting non-existant profile fields returns undef'); ##Check for valid profileField access, even if it is not cached in the user object. -my $newProfileField = WebGUI::ProfileField->create($session, 'testField', {dataDefault => 'this is a test'}); +my $newProfileField = WebGUI::ProfileField->create($session, 'testField', {dataDefault => 'this is a test', fieldType => 'Text'}); is($user->profileField('testField'), 'this is a test', 'getting profile fields not cached in the user object returns the profile field default'); ok(!$user->profileField('wg_privacySettings'), '... wg_privacySettings may not be retrieved'); @@ -1004,14 +1006,28 @@ is ($inmate->getInboxAddresses, '37927@textme.com', 'getInboxAddresses: can get $inmate->profileField('receiveInboxSmsNotifications', 0); is ($inmate->getInboxAddresses, '', 'getInboxAddresses: can get no SMS and no email, even with profile info present'); -END { - foreach my $testGroup ($expiredGroup, values %groupSet) { - if (defined $testGroup and ref $testGroup eq 'WebGUI::Group') { - $testGroup->delete; - } - } +################################################################ +# +# delete +# +################################################################ - ##Note, do not delete the visitor account. That would be really bad +##Specifically, cleaning up Address books + +my $shopUser = WebGUI::User->create($session); +WebGUI::Test->usersToDelete($shopUser); +$session->user({user => $shopUser}); +my $book = WebGUI::Shop::AddressBook->create($session); +is ($book->get('userId'), $shopUser->userId, 'delete: Address book created with proper user'); +my $bookId = $book->getId; +$shopUser->delete; +undef $book; +eval { $book = WebGUI::Shop::AddressBook->new($session, $bookId); }; +my $e = Exception::Class->caught(); +diag ref $e; +isa_ok($e, 'WebGUI::Error::ObjectNotFound', '... cleans up the address book'); + +END { $profileField->set(\%originalFieldData); $aliasProfile->set(\%originalAliasProfile); @@ -1022,8 +1038,6 @@ END { $newProfileField->delete() if $newProfileField; - $session->setting->set('smsGateway', $origSmsGateway); - $testCache->flush; }