1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00
phorge-phorge/resources/sql/autopatches/20150602.mlist.2.php
epriestley 249ee9f104 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
2015-06-03 18:42:35 -07:00

145 lines
3.7 KiB
PHP

<?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";
}