Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / metamta / management / PhabricatorMailManagementReceiveTestWorkflow.php
blob73917a2d84077ffa01f99a68d05579205ccf5161
1 <?php
3 final class PhabricatorMailManagementReceiveTestWorkflow
4 extends PhabricatorMailManagementWorkflow {
6 protected function didConstruct() {
7 $this
8 ->setName('receive-test')
9 ->setSynopsis(
10 pht(
11 'Simulate receiving mail. This is primarily useful if you are '.
12 'developing new mail receivers.'))
13 ->setExamples(
14 '**receive-test** --as alincoln --to D123 < body.txt')
15 ->setArguments(
16 array(
17 array(
18 'name' => 'as',
19 'param' => 'user',
20 'help' => pht('Act as the specified user.'),
22 array(
23 'name' => 'from',
24 'param' => 'email',
25 'help' => pht('Simulate mail delivery "From:" the given user.'),
27 array(
28 'name' => 'to',
29 'param' => 'object',
30 'help' => pht('Simulate mail delivery "To:" the given object.'),
32 array(
33 'name' => 'cc',
34 'param' => 'address',
35 'help' => pht('Simulate a mail delivery "Cc:" address.'),
36 'repeat' => true,
38 ));
41 public function execute(PhutilArgumentParser $args) {
42 $viewer = $this->getViewer();
43 $console = PhutilConsole::getConsole();
45 $to = $args->getArg('to');
46 if (!$to) {
47 throw new PhutilArgumentUsageException(
48 pht(
49 "Use '%s' to specify the receiving object or email address.",
50 '--to'));
53 $to_application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
54 ->setViewer($this->getViewer())
55 ->withAddresses(array($to))
56 ->executeOne();
58 $as = $args->getArg('as');
59 if (!$as && $to_application_email) {
60 $default_phid = $to_application_email->getConfigValue(
61 PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR);
62 if ($default_phid) {
63 $default_user = id(new PhabricatorPeopleQuery())
64 ->setViewer($this->getViewer())
65 ->withPHIDs(array($default_phid))
66 ->executeOne();
67 if ($default_user) {
68 $as = $default_user->getUsername();
73 if (!$as) {
74 throw new PhutilArgumentUsageException(
75 pht("Use '--as' to specify the acting user."));
78 $user = id(new PhabricatorPeopleQuery())
79 ->setViewer($this->getViewer())
80 ->withUsernames(array($as))
81 ->executeOne();
82 if (!$user) {
83 throw new PhutilArgumentUsageException(
84 pht("No such user '%s' exists.", $as));
88 $from = $args->getArg('from');
89 if (!$from) {
90 $from = $user->loadPrimaryEmail()->getAddress();
93 $cc = $args->getArg('cc');
95 $console->writeErr("%s\n", pht('Reading message body from stdin...'));
96 $body = file_get_contents('php://stdin');
98 $received = new PhabricatorMetaMTAReceivedMail();
99 $header_content = array(
100 'Message-ID' => Filesystem::readRandomCharacters(12),
101 'From' => $from,
102 'Cc' => implode(', ', $cc),
105 if (preg_match('/.+@.+/', $to)) {
106 $header_content['to'] = $to;
107 } else {
109 // We allow the user to use an object name instead of a real address
110 // as a convenience. To build the mail, we build a similar message and
111 // look for a receiver which will accept it.
113 // In the general case, mail may be processed by multiple receivers,
114 // but mail to objects only ever has one receiver today.
116 $pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
118 $raw_target = $to.'+1+'.$pseudohash;
119 $target = new PhutilEmailAddress($raw_target.'@local.cli');
121 $pseudomail = id(new PhabricatorMetaMTAReceivedMail())
122 ->setHeaders(
123 array(
124 'to' => $raw_target,
127 $receivers = id(new PhutilClassMapQuery())
128 ->setAncestorClass('PhabricatorMailReceiver')
129 ->setFilterMethod('isEnabled')
130 ->execute();
132 $receiver = null;
133 foreach ($receivers as $possible_receiver) {
134 $possible_receiver = id(clone $possible_receiver)
135 ->setViewer($viewer)
136 ->setSender($user);
138 if (!$possible_receiver->canAcceptMail($pseudomail, $target)) {
139 continue;
141 $receiver = $possible_receiver;
142 break;
145 if (!$receiver) {
146 throw new Exception(
147 pht("No configured mail receiver can accept mail to '%s'.", $to));
150 if (!($receiver instanceof PhabricatorObjectMailReceiver)) {
151 $class = get_class($receiver);
152 throw new Exception(
153 pht(
154 "Receiver '%s' accepts mail to '%s', but is not a ".
155 "subclass of PhabricatorObjectMailReceiver.",
156 $class,
157 $to));
160 $object = $receiver->loadMailReceiverObject($to, $user);
161 if (!$object) {
162 throw new Exception(pht("No such object '%s'!", $to));
165 $mail_key = PhabricatorMetaMTAMailProperties::loadMailKey($object);
167 $hash = PhabricatorObjectMailReceiver::computeMailHash(
168 $mail_key,
169 $user->getPHID());
171 $header_content['to'] = $to.'+'.$user->getID().'+'.$hash.'@test.com';
174 $received->setHeaders($header_content);
175 $received->setBodies(
176 array(
177 'text' => $body,
180 $received->save();
181 $received->processReceivedMail();
183 $console->writeErr(
184 "%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n",
185 pht('Mail received! You can view details by running this command:'),
186 $received->getID());