1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Migrate mailing lists to mailing list users

Summary:
Ref T8387. This migrates lists in the database to users, and replaces all subscriptions.

This won't update Herald rules or saved search queries, but they're presumably rare and infeasibly complex to migrate.

Test Plan: This migration is relatively re-runnable, so I ran it a bunch of times with different setups using `bin/storage adjust --apply`. It successfully migrated lists into users and replaced them in all the places they were subscribed.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: eadler, epriestley

Maniphest Tasks: T8387

Differential Revision: https://secure.phabricator.com/D13128
This commit is contained in:
epriestley 2015-06-02 15:10:55 -07:00
parent e0a3e6ba3b
commit 249ee9f104

View file

@ -0,0 +1,145 @@
<?php
$conn_w = id(new PhabricatorMetaMTAMail())->establishConnection('w');
$lists = new LiskRawMigrationIterator($conn_w, 'metamta_mailinglist');
echo pht('Migrating mailing lists...')."\n";
foreach ($lists as $list) {
$name = $list['name'];
$email = $list['email'];
$uri = $list['uri'];
$old_phid = $list['phid'];
$username = preg_replace('/[^a-zA-Z0-9_-]+/', '-', $name);
$username = preg_replace('/-{2,}/', '-', $username);
$username = trim($username, '-');
if (!strlen($username)) {
$username = 'mailinglist';
}
$username .= '-list';
$username_okay = false;
for ($suffix = 1; $suffix <= 9; $suffix++) {
if ($suffix == 1) {
$effective_username = $username;
} else {
$effective_username = $username.$suffix;
}
$collision = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withUsernames(array($effective_username))
->executeOne();
if (!$collision) {
$username_okay = true;
break;
}
}
if (!$username_okay) {
echo pht(
'Failed to migrate mailing list "%s": unable to generate a unique '.
'username for it.')."\n";
continue;
}
$username = $effective_username;
if (!PhabricatorUser::validateUsername($username)) {
echo pht(
'Failed to migrate mailing list "%s": unable to generate a valid '.
'username for it.',
$name)."\n";
continue;
}
$address = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$email);
if ($address) {
echo pht(
'Failed to migrate mailing list "%s": an existing user already '.
'has the email address "%s".',
$name,
$email)."\n";
continue;
}
$user = id(new PhabricatorUser())
->setUsername($username)
->setRealName(pht('Mailing List "%s"', $name))
->setIsApproved(1)
->setIsMailingList(1);
$email_object = id(new PhabricatorUserEmail())
->setAddress($email)
->setIsVerified(1);
try {
id(new PhabricatorUserEditor())
->setActor($user)
->createNewUser($user, $email_object);
} catch (Exception $ex) {
echo pht(
'Failed to migrate mailing list "%s": %s.',
$name,
$ex->getMessage())."\n";
continue;
}
$new_phid = $user->getPHID();
// NOTE: After the PHID type is removed we can't use any Edge code to
// modify edges.
$edge_type = PhabricatorSubscribedToObjectEdgeType::EDGECONST;
$edge_inverse = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
$map = PhabricatorPHIDType::getAllTypes();
foreach ($map as $type => $spec) {
try {
$object = $spec->newObject();
if (!$object) {
continue;
}
$object_conn_w = $object->establishConnection('w');
queryfx(
$object_conn_w,
'UPDATE %T SET dst = %s WHERE dst = %s AND type = %s',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$new_phid,
$old_phid,
$edge_inverse);
} catch (Exception $ex) {
// Just ignore these; they're mostly tables not existing.
continue;
}
}
try {
$dst_phids = queryfx_all(
$conn_w,
'SELECT dst FROM %T WHERE src = %s AND type = %s',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$old_phid,
$edge_type);
if ($dst_phids) {
$editor = new PhabricatorEdgeEditor();
foreach ($dst_phids as $dst_phid) {
$editor->addEdge($new_phid, $edge_type, $dst_phid['dst']);
}
$editor->save();
}
} catch (Exception $ex) {
echo pht(
'Unable to migrate some inverse edges for mailing list "%s": %s.',
$name,
$ex->getMessage())."\n";
continue;
}
echo pht(
'Migrated mailing list "%s" to mailing list user "%s".',
$name,
$user->getUsername())."\n";
}