Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / metamta / management / PhabricatorMailManagementShowOutboundWorkflow.php
blobf29a63c2eb197ce6251c7dc0e51ad6737632d7c1
1 <?php
3 final class PhabricatorMailManagementShowOutboundWorkflow
4 extends PhabricatorMailManagementWorkflow {
6 protected function didConstruct() {
7 $this
8 ->setName('show-outbound')
9 ->setSynopsis(pht('Show diagnostic details about outbound mail.'))
10 ->setExamples(
11 '**show-outbound** --id 1 --id 2')
12 ->setArguments(
13 array(
14 array(
15 'name' => 'id',
16 'param' => 'id',
17 'help' => pht('Show details about outbound mail with given ID.'),
18 'repeat' => true,
20 array(
21 'name' => 'dump-html',
22 'help' => pht(
23 'Dump the HTML body of the mail. You can redirect it to a '.
24 'file and then open it in a browser.'),
26 ));
29 public function execute(PhutilArgumentParser $args) {
30 $console = PhutilConsole::getConsole();
32 $ids = $args->getArg('id');
33 if (!$ids) {
34 throw new PhutilArgumentUsageException(
35 pht(
36 "Use the '%s' flag to specify one or more messages to show.",
37 '--id'));
40 foreach ($ids as $id) {
41 if (!ctype_digit($id)) {
42 throw new PhutilArgumentUsageException(
43 pht(
44 'Argument "%s" is not a valid message ID.',
45 $id));
49 $messages = id(new PhabricatorMetaMTAMail())->loadAllWhere(
50 'id IN (%Ld)',
51 $ids);
53 if ($ids) {
54 $ids = array_fuse($ids);
55 $missing = array_diff_key($ids, $messages);
56 if ($missing) {
57 throw new PhutilArgumentUsageException(
58 pht(
59 'Some specified messages do not exist: %s',
60 implode(', ', array_keys($missing))));
64 $last_key = last_key($messages);
65 foreach ($messages as $message_key => $message) {
66 if ($args->getArg('dump-html')) {
67 $html_body = $message->getHTMLBody();
68 if (strlen($html_body)) {
69 $template =
70 "<!doctype html><html><body>{$html_body}</body></html>";
71 $console->writeOut("%s\n", $html_body);
72 } else {
73 $console->writeErr(
74 "%s\n",
75 pht('(This message has no HTML body.)'));
77 continue;
80 $info = array();
82 $info[] = $this->newSectionHeader(pht('PROPERTIES'));
83 $info[] = pht('ID: %d', $message->getID());
84 $info[] = pht('Status: %s', $message->getStatus());
85 $info[] = pht('Related PHID: %s', $message->getRelatedPHID());
86 $info[] = pht('Message: %s', $message->getMessage());
88 $ignore = array(
89 'body' => true,
90 'body.sent' => true,
91 'html-body' => true,
92 'headers' => true,
93 'attachments' => true,
94 'headers.sent' => true,
95 'headers.unfiltered' => true,
96 'authors.sent' => true,
99 $info[] = null;
100 $info[] = $this->newSectionHeader(pht('PARAMETERS'));
101 $parameters = $message->getParameters();
102 foreach ($parameters as $key => $value) {
103 if (isset($ignore[$key])) {
104 continue;
107 if (!is_scalar($value)) {
108 $value = json_encode($value);
111 $info[] = pht('%s: %s', $key, $value);
114 $info[] = null;
115 $info[] = $this->newSectionHeader(pht('HEADERS'));
117 $headers = $message->getDeliveredHeaders();
118 if (!$headers) {
119 $headers = array();
122 $unfiltered = $message->getUnfilteredHeaders();
123 if (!$unfiltered) {
124 $unfiltered = array();
127 $header_map = array();
128 foreach ($headers as $header) {
129 list($name, $value) = $header;
130 $header_map[$name.':'.$value] = true;
133 foreach ($unfiltered as $header) {
134 list($name, $value) = $header;
135 $was_sent = isset($header_map[$name.':'.$value]);
137 if ($was_sent) {
138 $marker = ' ';
139 } else {
140 $marker = '#';
143 $info[] = "{$marker} {$name}: {$value}";
146 $attachments = idx($parameters, 'attachments');
147 if ($attachments) {
148 $info[] = null;
150 $info[] = $this->newSectionHeader(pht('ATTACHMENTS'));
152 foreach ($attachments as $attachment) {
153 $info[] = idx($attachment, 'filename', pht('Unnamed File'));
157 $all_actors = $message->loadAllActors();
159 $actors = $message->getDeliveredActors();
160 if ($actors) {
161 $info[] = null;
163 $info[] = $this->newSectionHeader(pht('RECIPIENTS'));
165 foreach ($actors as $actor_phid => $actor_info) {
166 $actor = idx($all_actors, $actor_phid);
167 if ($actor) {
168 $actor_name = coalesce($actor->getName(), $actor_phid);
169 } else {
170 $actor_name = $actor_phid;
173 $deliverable = $actor_info['deliverable'];
174 if ($deliverable) {
175 $info[] = ' '.$actor_name;
176 } else {
177 $info[] = '! '.$actor_name;
180 $reasons = $actor_info['reasons'];
181 foreach ($reasons as $reason) {
182 $name = PhabricatorMetaMTAActor::getReasonName($reason);
183 $desc = PhabricatorMetaMTAActor::getReasonDescription($reason);
184 $info[] = ' - '.$name.': '.$desc;
189 $info[] = null;
190 $info[] = $this->newSectionHeader(pht('TEXT BODY'));
191 if (strlen($message->getBody())) {
192 $info[] = tsprintf('%B', $message->getBody());
193 } else {
194 $info[] = pht('(This message has no text body.)');
197 $delivered_body = $message->getDeliveredBody();
198 if ($delivered_body !== null) {
199 $info[] = null;
200 $info[] = $this->newSectionHeader(pht('BODY AS DELIVERED'), true);
201 $info[] = tsprintf('%B', $delivered_body);
204 $info[] = null;
205 $info[] = $this->newSectionHeader(pht('HTML BODY'));
206 if (strlen($message->getHTMLBody())) {
207 $info[] = $message->getHTMLBody();
208 $info[] = null;
209 } else {
210 $info[] = pht('(This message has no HTML body.)');
211 $info[] = null;
214 $console->writeOut('%s', implode("\n", $info));
216 if ($message_key != $last_key) {
217 $console->writeOut("\n%s\n\n", str_repeat('-', 80));
222 private function newSectionHeader($label, $emphasize = false) {
223 if ($emphasize) {
224 return tsprintf('**<bg:yellow> %s </bg>**', $label);
225 } else {
226 return tsprintf('**<bg:blue> %s </bg>**', $label);