public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $ids = $args->getArg('id'); if (!$ids) { throw new PhutilArgumentUsageException(pht("Use the '%s' flag to specify one or more messages to show.", '--id')); } $messages = id(new PhabricatorMetaMTAMail())->loadAllWhere('id IN (%Ld)', $ids); if ($ids) { $ids = array_fuse($ids); $missing = array_diff_key($ids, $messages); if ($missing) { throw new PhutilArgumentUsageException(pht('Some specified messages do not exist: %s', implode(', ', array_keys($missing)))); } } $last_key = last_key($messages); foreach ($messages as $message_key => $message) { if ($args->getArg('dump-html')) { $html_body = $message->getHTMLBody(); if (strlen($html_body)) { $template = "<!doctype html><html><body>{$html_body}</body></html>"; $console->writeOut("%s\n", $html_body); } else { $console->writeErr("%s\n", pht('(This message has no HTML body.)')); } continue; } $info = array(); $info[] = pht('PROPERTIES'); $info[] = pht('ID: %d', $message->getID()); $info[] = pht('Status: %s', $message->getStatus()); $info[] = pht('Related PHID: %s', $message->getRelatedPHID()); $info[] = pht('Message: %s', $message->getMessage()); $ignore = array('body' => true, 'html-body' => true, 'headers' => true, 'attachments' => true, 'headers.sent' => true, 'authors.sent' => true); $info[] = null; $info[] = pht('PARAMETERS'); $parameters = $message->getParameters(); foreach ($parameters as $key => $value) { if (isset($ignore[$key])) { continue; } if (!is_scalar($value)) { $value = json_encode($value); } $info[] = pht('%s: %s', $key, $value); } $info[] = null; $info[] = pht('HEADERS'); $headers = $message->getDeliveredHeaders(); if (!$headers) { $headers = $message->generateHeaders(); } foreach ($headers as $header) { list($name, $value) = $header; $info[] = "{$name}: {$value}"; } $attachments = idx($parameters, 'attachments'); if ($attachments) { $info[] = null; $info[] = pht('ATTACHMENTS'); foreach ($attachments as $attachment) { $info[] = idx($attachment, 'filename', pht('Unnamed File')); } } $all_actors = $message->loadAllActors(); $actors = $message->getDeliveredActors(); if ($actors) { $info[] = null; $info[] = pht('RECIPIENTS'); foreach ($actors as $actor_phid => $actor_info) { $actor = idx($all_actors, $actor_phid); if ($actor) { $actor_name = coalesce($actor->getName(), $actor_phid); } else { $actor_name = $actor_phid; } $deliverable = $actor_info['deliverable']; if ($deliverable) { $info[] = ' ' . $actor_name; } else { $info[] = '! ' . $actor_name; } $reasons = $actor_info['reasons']; foreach ($reasons as $reason) { $name = PhabricatorMetaMTAActor::getReasonName($reason); $desc = PhabricatorMetaMTAActor::getReasonDescription($reason); $info[] = ' - ' . $name . ': ' . $desc; } } } $info[] = null; $info[] = pht('TEXT BODY'); if (strlen($message->getBody())) { $info[] = $message->getBody(); } else { $info[] = pht('(This message has no text body.)'); } $info[] = null; $info[] = pht('HTML BODY'); if (strlen($message->getHTMLBody())) { $info[] = $message->getHTMLBody(); $info[] = null; } else { $info[] = pht('(This message has no HTML body.)'); } $console->writeOut('%s', implode("\n", $info)); if ($message_key != $last_key) { $console->writeOut("\n%s\n\n", str_repeat('-', 80)); } } }
private function buildDeliveryProperties(PhabricatorMetaMTAMail $mail) { $viewer = $this->getViewer(); $properties = id(new PHUIPropertyListView())->setUser($viewer); $actors = $mail->getDeliveredActors(); $reasons = null; if (!$actors) { if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) { $delivery = $this->renderEmptyMessage(pht('This message has not been delivered yet, so delivery information ' . 'is not available.')); } else { $delivery = $this->renderEmptyMessage(pht('This is an older message that predates recording delivery ' . 'information, so none is available.')); } } else { $actor = idx($actors, $viewer->getPHID()); if (!$actor) { $delivery = phutil_tag('em', array(), pht('This message was not delivered to you.')); } else { $deliverable = $actor['deliverable']; if ($deliverable) { $delivery = pht('Delivered'); } else { $delivery = pht('Voided'); } $reasons = id(new PHUIStatusListView()); $reason_codes = $actor['reasons']; if (!$reason_codes) { $reason_codes = array(PhabricatorMetaMTAActor::REASON_NONE); } $icon_yes = 'fa-check green'; $icon_no = 'fa-times red'; foreach ($reason_codes as $reason) { $target = phutil_tag('strong', array(), PhabricatorMetaMTAActor::getReasonName($reason)); if (PhabricatorMetaMTAActor::isDeliveryReason($reason)) { $icon = $icon_yes; } else { $icon = $icon_no; } $item = id(new PHUIStatusItemView())->setIcon($icon)->setTarget($target)->setNote(PhabricatorMetaMTAActor::getReasonDescription($reason)); $reasons->addItem($item); } } } $properties->addProperty(pht('Delivery'), $delivery); if ($reasons) { $properties->addProperty(pht('Reasons'), $reasons); $properties->addProperty(null, $this->renderEmptyMessage(pht('Delivery reasons are listed from weakest to strongest.'))); } $properties->addSectionHeader(pht('Routing Rules'), 'fa-paper-plane-o'); $map = $mail->getDeliveredRoutingMap(); $routing_detail = null; if ($map === null) { if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) { $routing_result = $this->renderEmptyMessage(pht('This message has not been sent yet, so routing rules have ' . 'not been computed.')); } else { $routing_result = $this->renderEmptyMessage(pht('This is an older message which predates routing rules.')); } } else { $rule = idx($map, $viewer->getPHID()); if ($rule === null) { $rule = idx($map, 'default'); } if ($rule === null) { $routing_result = $this->renderEmptyMessage(pht('No routing rules applied when delivering this message to you.')); } else { $rule_const = $rule['rule']; $reason_phid = $rule['reason']; switch ($rule_const) { case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION: $routing_result = pht('This message was routed as a notification because it ' . 'matched %s.', $viewer->renderHandle($reason_phid)->render()); break; case PhabricatorMailRoutingRule::ROUTE_AS_MAIL: $routing_result = pht('This message was routed as an email because it matched %s.', $viewer->renderHandle($reason_phid)->render()); break; default: $routing_result = pht('Unknown routing rule "%s".', $rule_const); break; } } $routing_rules = $mail->getDeliveredRoutingRules(); if ($routing_rules) { $rules = array(); foreach ($routing_rules as $rule) { $phids = idx($rule, 'phids'); if ($phids === null) { $rules[] = $rule; } else { if (in_array($viewer->getPHID(), $phids)) { $rules[] = $rule; } } } // Reorder rules by strength. foreach ($rules as $key => $rule) { $const = $rule['routingRule']; $phids = $rule['phids']; if ($phids === null) { $type = 'A'; } else { $type = 'B'; } $rules[$key]['strength'] = sprintf('~%s%08d', $type, PhabricatorMailRoutingRule::getRuleStrength($const)); } $rules = isort($rules, 'strength'); $routing_detail = id(new PHUIStatusListView()); foreach ($rules as $rule) { $const = $rule['routingRule']; $phids = $rule['phids']; $name = PhabricatorMailRoutingRule::getRuleName($const); $icon = PhabricatorMailRoutingRule::getRuleIcon($const); $color = PhabricatorMailRoutingRule::getRuleColor($const); if ($phids === null) { $kind = pht('Global'); } else { $kind = pht('Personal'); } $target = array($kind, ': ', $name); $target = phutil_tag('strong', array(), $target); $item = id(new PHUIStatusItemView())->setTarget($target)->setNote($viewer->renderHandle($rule['reasonPHID']))->setIcon($icon, $color); $routing_detail->addItem($item); } } } $properties->addProperty(pht('Effective Rule'), $routing_result); if ($routing_detail !== null) { $properties->addProperty(pht('All Matching Rules'), $routing_detail); $properties->addProperty(null, $this->renderEmptyMessage(pht('Matching rules are listed from weakest to strongest.'))); } return $properties; }