@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+145
+145
resources/sql/autopatches/20150602.mlist.2.php
··· 1 + <?php 2 + 3 + $conn_w = id(new PhabricatorMetaMTAMail())->establishConnection('w'); 4 + $lists = new LiskRawMigrationIterator($conn_w, 'metamta_mailinglist'); 5 + 6 + echo pht('Migrating mailing lists...')."\n"; 7 + 8 + foreach ($lists as $list) { 9 + $name = $list['name']; 10 + $email = $list['email']; 11 + $uri = $list['uri']; 12 + $old_phid = $list['phid']; 13 + 14 + $username = preg_replace('/[^a-zA-Z0-9_-]+/', '-', $name); 15 + $username = preg_replace('/-{2,}/', '-', $username); 16 + $username = trim($username, '-'); 17 + if (!strlen($username)) { 18 + $username = 'mailinglist'; 19 + } 20 + $username .= '-list'; 21 + 22 + $username_okay = false; 23 + for ($suffix = 1; $suffix <= 9; $suffix++) { 24 + if ($suffix == 1) { 25 + $effective_username = $username; 26 + } else { 27 + $effective_username = $username.$suffix; 28 + } 29 + 30 + $collision = id(new PhabricatorPeopleQuery()) 31 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 32 + ->withUsernames(array($effective_username)) 33 + ->executeOne(); 34 + if (!$collision) { 35 + $username_okay = true; 36 + break; 37 + } 38 + } 39 + 40 + if (!$username_okay) { 41 + echo pht( 42 + 'Failed to migrate mailing list "%s": unable to generate a unique '. 43 + 'username for it.')."\n"; 44 + continue; 45 + } 46 + 47 + $username = $effective_username; 48 + if (!PhabricatorUser::validateUsername($username)) { 49 + echo pht( 50 + 'Failed to migrate mailing list "%s": unable to generate a valid '. 51 + 'username for it.', 52 + $name)."\n"; 53 + continue; 54 + } 55 + 56 + $address = id(new PhabricatorUserEmail())->loadOneWhere( 57 + 'address = %s', 58 + $email); 59 + if ($address) { 60 + echo pht( 61 + 'Failed to migrate mailing list "%s": an existing user already '. 62 + 'has the email address "%s".', 63 + $name, 64 + $email)."\n"; 65 + continue; 66 + } 67 + 68 + $user = id(new PhabricatorUser()) 69 + ->setUsername($username) 70 + ->setRealName(pht('Mailing List "%s"', $name)) 71 + ->setIsApproved(1) 72 + ->setIsMailingList(1); 73 + 74 + $email_object = id(new PhabricatorUserEmail()) 75 + ->setAddress($email) 76 + ->setIsVerified(1); 77 + 78 + try { 79 + id(new PhabricatorUserEditor()) 80 + ->setActor($user) 81 + ->createNewUser($user, $email_object); 82 + } catch (Exception $ex) { 83 + echo pht( 84 + 'Failed to migrate mailing list "%s": %s.', 85 + $name, 86 + $ex->getMessage())."\n"; 87 + continue; 88 + } 89 + 90 + $new_phid = $user->getPHID(); 91 + 92 + // NOTE: After the PHID type is removed we can't use any Edge code to 93 + // modify edges. 94 + 95 + $edge_type = PhabricatorSubscribedToObjectEdgeType::EDGECONST; 96 + $edge_inverse = PhabricatorObjectHasSubscriberEdgeType::EDGECONST; 97 + 98 + $map = PhabricatorPHIDType::getAllTypes(); 99 + foreach ($map as $type => $spec) { 100 + try { 101 + $object = $spec->newObject(); 102 + if (!$object) { 103 + continue; 104 + } 105 + $object_conn_w = $object->establishConnection('w'); 106 + queryfx( 107 + $object_conn_w, 108 + 'UPDATE %T SET dst = %s WHERE dst = %s AND type = %s', 109 + PhabricatorEdgeConfig::TABLE_NAME_EDGE, 110 + $new_phid, 111 + $old_phid, 112 + $edge_inverse); 113 + } catch (Exception $ex) { 114 + // Just ignore these; they're mostly tables not existing. 115 + continue; 116 + } 117 + } 118 + 119 + try { 120 + $dst_phids = queryfx_all( 121 + $conn_w, 122 + 'SELECT dst FROM %T WHERE src = %s AND type = %s', 123 + PhabricatorEdgeConfig::TABLE_NAME_EDGE, 124 + $old_phid, 125 + $edge_type); 126 + if ($dst_phids) { 127 + $editor = new PhabricatorEdgeEditor(); 128 + foreach ($dst_phids as $dst_phid) { 129 + $editor->addEdge($new_phid, $edge_type, $dst_phid['dst']); 130 + } 131 + $editor->save(); 132 + } 133 + } catch (Exception $ex) { 134 + echo pht( 135 + 'Unable to migrate some inverse edges for mailing list "%s": %s.', 136 + $name, 137 + $ex->getMessage())."\n"; 138 + continue; 139 + } 140 + 141 + echo pht( 142 + 'Migrated mailing list "%s" to mailing list user "%s".', 143 + $name, 144 + $user->getUsername())."\n"; 145 + }