@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<?php
2
3$conn_r = id(new PhabricatorMetaMTAMail())->establishConnection('r');
4
5$rows = queryfx_all(
6 $conn_r,
7 'SELECT phid, email FROM %T',
8 'metamta_mailinglist');
9if (!$rows) {
10 echo pht('No mailing lists to migrate.')."\n";
11 return;
12}
13
14$list_map = array();
15foreach ($rows as $row) {
16 $list_map[phutil_utf8_strtolower($row['email'])] = $row['phid'];
17}
18
19$emails = id(new PhabricatorUserEmail())->loadAllWhere(
20 'address IN (%Ls)',
21 array_keys($list_map));
22if (!$emails) {
23 echo pht('No mailing lists match addresses.')."\n";
24 return;
25}
26
27// Create a map from old mailing list PHIDs to new user PHIDs.
28$map = array();
29foreach ($emails as $email) {
30 $user_phid = $email->getUserPHID();
31 if (!$user_phid) {
32 continue;
33 }
34
35 $address = $email->getAddress();
36 $address = phutil_utf8_strtolower($address);
37 if (isset($list_map[$address])) {
38 $map[$list_map[$address]] = $user_phid;
39 }
40}
41
42if (!$map) {
43 echo pht('No mailing lists match users.')."\n";
44 return;
45}
46
47echo pht('Migrating Herald conditions which use mailing lists..')."\n";
48
49$table = new HeraldCondition();
50$conn_w = $table->establishConnection('w');
51foreach (new LiskMigrationIterator($table) as $condition) {
52 $name = $condition->getFieldName();
53 if ($name == 'cc') {
54 // Okay, we can migrate these.
55 } else {
56 // This is not a condition type which has mailing lists in its value, so
57 // don't try to migrate it.
58 continue;
59 }
60
61 $value = $condition->getValue();
62 if (!is_array($value)) {
63 // Only migrate PHID lists.
64 continue;
65 }
66
67 foreach ($value as $v) {
68 if (!is_string($v)) {
69 // Only migrate PHID lists where all members are PHIDs.
70 continue 2;
71 }
72 }
73
74 $new = array();
75 $any_change = false;
76 foreach ($value as $v) {
77 if (isset($map[$v])) {
78 $new[] = $map[$v];
79 $any_change = true;
80 } else {
81 $new[] = $v;
82 }
83 }
84
85 if (!$any_change) {
86 continue;
87 }
88
89 $id = $condition->getID();
90
91 queryfx(
92 $conn_w,
93 'UPDATE %T SET value = %s WHERE id = %d',
94 $table->getTableName(),
95 json_encode($new),
96 $id);
97
98
99 echo pht('Updated mailing lists in Herald condition %d.', $id)."\n";
100}
101
102$table = new HeraldActionRecord();
103$conn_w = $table->establishConnection('w');
104foreach (new LiskMigrationIterator($table) as $action) {
105 $name = $action->getAction();
106 if ($name == 'addcc' || $name == 'remcc') {
107 // Okay, we can migrate these.
108 } else {
109 // This is not an action type which has mailing lists in its targets, so
110 // don't try to migrate it.
111 continue;
112 }
113
114 $value = $action->getTarget();
115 if (!is_array($value)) {
116 // Only migrate PHID lists.
117 continue;
118 }
119
120 foreach ($value as $v) {
121 if (!is_string($v)) {
122 // Only migrate PHID lists where all members are PHIDs.
123 continue 2;
124 }
125 }
126
127 $new = array();
128 $any_change = false;
129 foreach ($value as $v) {
130 if (isset($map[$v])) {
131 $new[] = $map[$v];
132 $any_change = true;
133 } else {
134 $new[] = $v;
135 }
136 }
137
138 if (!$any_change) {
139 continue;
140 }
141
142 $id = $action->getID();
143
144 queryfx(
145 $conn_w,
146 'UPDATE %T SET target = %s WHERE id = %d',
147 $table->getTableName(),
148 json_encode($new),
149 $id);
150
151 echo pht('Updated mailing lists in Herald action %d.', $id)."\n";
152}