3 final class PhabricatorMailManagementShowOutboundWorkflow
4 extends PhabricatorMailManagementWorkflow
{
6 protected function didConstruct() {
8 ->setName('show-outbound')
9 ->setSynopsis(pht('Show diagnostic details about outbound mail.'))
11 '**show-outbound** --id 1 --id 2')
17 'help' => pht('Show details about outbound mail with given ID.'),
21 'name' => 'dump-html',
23 'Dump the HTML body of the mail. You can redirect it to a '.
24 'file and then open it in a browser.'),
29 public function execute(PhutilArgumentParser
$args) {
30 $console = PhutilConsole
::getConsole();
32 $ids = $args->getArg('id');
34 throw new PhutilArgumentUsageException(
36 "Use the '%s' flag to specify one or more messages to show.",
40 foreach ($ids as $id) {
41 if (!ctype_digit($id)) {
42 throw new PhutilArgumentUsageException(
44 'Argument "%s" is not a valid message ID.',
49 $messages = id(new PhabricatorMetaMTAMail())->loadAllWhere(
54 $ids = array_fuse($ids);
55 $missing = array_diff_key($ids, $messages);
57 throw new PhutilArgumentUsageException(
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)) {
70 "<!doctype html><html><body>{$html_body}</body></html>";
71 $console->writeOut("%s\n", $html_body);
75 pht('(This message has no HTML body.)'));
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());
93 'attachments' => true,
94 'headers.sent' => true,
95 'headers.unfiltered' => true,
96 'authors.sent' => true,
100 $info[] = $this->newSectionHeader(pht('PARAMETERS'));
101 $parameters = $message->getParameters();
102 foreach ($parameters as $key => $value) {
103 if (isset($ignore[$key])) {
107 if (!is_scalar($value)) {
108 $value = json_encode($value);
111 $info[] = pht('%s: %s', $key, $value);
115 $info[] = $this->newSectionHeader(pht('HEADERS'));
117 $headers = $message->getDeliveredHeaders();
122 $unfiltered = $message->getUnfilteredHeaders();
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]);
143 $info[] = "{$marker} {$name}: {$value}";
146 $attachments = idx($parameters, 'attachments');
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();
163 $info[] = $this->newSectionHeader(pht('RECIPIENTS'));
165 foreach ($actors as $actor_phid => $actor_info) {
166 $actor = idx($all_actors, $actor_phid);
168 $actor_name = coalesce($actor->getName(), $actor_phid);
170 $actor_name = $actor_phid;
173 $deliverable = $actor_info['deliverable'];
175 $info[] = ' '.$actor_name;
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;
190 $info[] = $this->newSectionHeader(pht('TEXT BODY'));
191 if (strlen($message->getBody())) {
192 $info[] = tsprintf('%B', $message->getBody());
194 $info[] = pht('(This message has no text body.)');
197 $delivered_body = $message->getDeliveredBody();
198 if ($delivered_body !== null) {
200 $info[] = $this->newSectionHeader(pht('BODY AS DELIVERED'), true);
201 $info[] = tsprintf('%B', $delivered_body);
205 $info[] = $this->newSectionHeader(pht('HTML BODY'));
206 if (strlen($message->getHTMLBody())) {
207 $info[] = $message->getHTMLBody();
210 $info[] = pht('(This message has no HTML body.)');
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) {
224 return tsprintf('**<bg:yellow> %s </bg>**', $label);
226 return tsprintf('**<bg:blue> %s </bg>**', $label);