Path: blob/master/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
12256 views
<?php12final class PhabricatorMetaMTAMailViewController3extends PhabricatorMetaMTAController {45public function handleRequest(AphrontRequest $request) {6$viewer = $this->getViewer();78$mail = id(new PhabricatorMetaMTAMailQuery())9->setViewer($viewer)10->withIDs(array($request->getURIData('id')))11->executeOne();12if (!$mail) {13return new Aphront404Response();14}1516if ($mail->hasSensitiveContent()) {17$title = pht('Content Redacted');18} else {19$title = $mail->getSubject();20}2122$header = id(new PHUIHeaderView())23->setHeader($title)24->setUser($viewer)25->setPolicyObject($mail)26->setHeaderIcon('fa-envelope');2728$status = $mail->getStatus();29$name = PhabricatorMailOutboundStatus::getStatusName($status);30$icon = PhabricatorMailOutboundStatus::getStatusIcon($status);31$color = PhabricatorMailOutboundStatus::getStatusColor($status);32$header->setStatus($icon, $color, $name);3334if ($mail->getMustEncrypt()) {35Javelin::initBehavior('phabricator-tooltips');36$header->addTag(37id(new PHUITagView())38->setType(PHUITagView::TYPE_SHADE)39->setColor('blue')40->setName(pht('Must Encrypt'))41->setIcon('fa-shield blue')42->addSigil('has-tooltip')43->setMetadata(44array(45'tip' => pht(46'Message content can only be transmitted over secure '.47'channels.'),48)));49}5051$crumbs = $this->buildApplicationCrumbs()52->addTextCrumb(pht('Mail %d', $mail->getID()))53->setBorder(true);5455$tab_group = id(new PHUITabGroupView())56->addTab(57id(new PHUITabView())58->setName(pht('Message'))59->setKey('message')60->appendChild($this->buildMessageProperties($mail)))61->addTab(62id(new PHUITabView())63->setName(pht('Headers'))64->setKey('headers')65->appendChild($this->buildHeaderProperties($mail)))66->addTab(67id(new PHUITabView())68->setName(pht('Delivery'))69->setKey('delivery')70->appendChild($this->buildDeliveryProperties($mail)))71->addTab(72id(new PHUITabView())73->setName(pht('Metadata'))74->setKey('metadata')75->appendChild($this->buildMetadataProperties($mail)));7677$header_view = id(new PHUIHeaderView())78->setHeader(pht('Mail'));7980$object_phid = $mail->getRelatedPHID();81if ($object_phid) {82$handles = $viewer->loadHandles(array($object_phid));83$handle = $handles[$object_phid];84if ($handle->isComplete() && $handle->getURI()) {85$view_button = id(new PHUIButtonView())86->setTag('a')87->setText(pht('View Object'))88->setIcon('fa-chevron-right')89->setHref($handle->getURI());9091$header_view->addActionLink($view_button);92}93}9495$object_box = id(new PHUIObjectBoxView())96->setHeader($header_view)97->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)98->addTabGroup($tab_group);99100$view = id(new PHUITwoColumnView())101->setHeader($header)102->setFooter($object_box);103104return $this->newPage()105->setTitle($title)106->setCrumbs($crumbs)107->setPageObjectPHIDs(array($mail->getPHID()))108->appendChild($view);109}110111private function buildMessageProperties(PhabricatorMetaMTAMail $mail) {112$viewer = $this->getViewer();113114$properties = id(new PHUIPropertyListView())115->setUser($viewer)116->setObject($mail);117118if ($mail->getFrom()) {119$from_str = $viewer->renderHandle($mail->getFrom());120} else {121$from_str = pht(122'Sent by %s',123PlatformSymbols::getPlatformServerName());124}125$properties->addProperty(126pht('From'),127$from_str);128129if ($mail->getToPHIDs()) {130$to_list = $viewer->renderHandleList($mail->getToPHIDs());131} else {132$to_list = pht('None');133}134$properties->addProperty(135pht('To'),136$to_list);137138if ($mail->getCcPHIDs()) {139$cc_list = $viewer->renderHandleList($mail->getCcPHIDs());140} else {141$cc_list = pht('None');142}143$properties->addProperty(144pht('Cc'),145$cc_list);146147$properties->addProperty(148pht('Sent'),149phabricator_datetime($mail->getDateCreated(), $viewer));150151$properties->addSectionHeader(152pht('Message'),153PHUIPropertyListView::ICON_SUMMARY);154155if ($mail->hasSensitiveContent()) {156$body = phutil_tag(157'em',158array(),159pht(160'The content of this mail is sensitive and it can not be '.161'viewed from the web UI.'));162} else {163$body = phutil_tag(164'div',165array(166'style' => 'white-space: pre-wrap',167),168$mail->getBody());169}170171$properties->addTextContent($body);172173$file_phids = $mail->getAttachmentFilePHIDs();174if ($file_phids) {175$properties->addProperty(176pht('Attached Files'),177$viewer->loadHandles($file_phids)->renderList());178}179180return $properties;181}182183private function buildHeaderProperties(PhabricatorMetaMTAMail $mail) {184$viewer = $this->getViewer();185186$properties = id(new PHUIPropertyListView())187->setUser($viewer)188->setStacked(true);189190$headers = $mail->getDeliveredHeaders();191if (!$headers) {192$headers = array();193}194195// Sort headers by name.196$headers = isort($headers, 0);197198foreach ($headers as $header) {199list($key, $value) = $header;200$properties->addProperty($key, $value);201}202203$encrypt_phids = $mail->getMustEncryptReasons();204if ($encrypt_phids) {205$properties->addProperty(206pht('Must Encrypt'),207$viewer->loadHandles($encrypt_phids)208->renderList());209}210211212return $properties;213}214215private function buildDeliveryProperties(PhabricatorMetaMTAMail $mail) {216$viewer = $this->getViewer();217218$properties = id(new PHUIPropertyListView())219->setUser($viewer);220221$actors = $mail->getDeliveredActors();222$reasons = null;223if (!$actors) {224if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {225$delivery = $this->renderEmptyMessage(226pht(227'This message has not been delivered yet, so delivery information '.228'is not available.'));229} else {230$delivery = $this->renderEmptyMessage(231pht(232'This is an older message that predates recording delivery '.233'information, so none is available.'));234}235} else {236$actor = idx($actors, $viewer->getPHID());237if (!$actor) {238$delivery = phutil_tag(239'em',240array(),241pht('This message was not delivered to you.'));242} else {243$deliverable = $actor['deliverable'];244if ($deliverable) {245$delivery = pht('Delivered');246} else {247$delivery = pht('Voided');248}249250$reasons = id(new PHUIStatusListView());251252$reason_codes = $actor['reasons'];253if (!$reason_codes) {254$reason_codes = array(255PhabricatorMetaMTAActor::REASON_NONE,256);257}258259$icon_yes = 'fa-check green';260$icon_no = 'fa-times red';261262foreach ($reason_codes as $reason) {263$target = phutil_tag(264'strong',265array(),266PhabricatorMetaMTAActor::getReasonName($reason));267268if (PhabricatorMetaMTAActor::isDeliveryReason($reason)) {269$icon = $icon_yes;270} else {271$icon = $icon_no;272}273274$item = id(new PHUIStatusItemView())275->setIcon($icon)276->setTarget($target)277->setNote(PhabricatorMetaMTAActor::getReasonDescription($reason));278279$reasons->addItem($item);280}281}282}283284$properties->addProperty(pht('Delivery'), $delivery);285if ($reasons) {286$properties->addProperty(pht('Reasons'), $reasons);287$properties->addProperty(288null,289$this->renderEmptyMessage(290pht(291'Delivery reasons are listed from weakest to strongest.')));292}293294$properties->addSectionHeader(295pht('Routing Rules'), 'fa-paper-plane-o');296297$map = $mail->getDeliveredRoutingMap();298$routing_detail = null;299if ($map === null) {300if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {301$routing_result = $this->renderEmptyMessage(302pht(303'This message has not been sent yet, so routing rules have '.304'not been computed.'));305} else {306$routing_result = $this->renderEmptyMessage(307pht(308'This is an older message which predates routing rules.'));309}310} else {311$rule = idx($map, $viewer->getPHID());312if ($rule === null) {313$rule = idx($map, 'default');314}315316if ($rule === null) {317$routing_result = $this->renderEmptyMessage(318pht(319'No routing rules applied when delivering this message to you.'));320} else {321$rule_const = $rule['rule'];322$reason_phid = $rule['reason'];323switch ($rule_const) {324case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION:325$routing_result = pht(326'This message was routed as a notification because it '.327'matched %s.',328$viewer->renderHandle($reason_phid)->render());329break;330case PhabricatorMailRoutingRule::ROUTE_AS_MAIL:331$routing_result = pht(332'This message was routed as an email because it matched %s.',333$viewer->renderHandle($reason_phid)->render());334break;335default:336$routing_result = pht('Unknown routing rule "%s".', $rule_const);337break;338}339}340341$routing_rules = $mail->getDeliveredRoutingRules();342if ($routing_rules) {343$rules = array();344foreach ($routing_rules as $rule) {345$phids = idx($rule, 'phids');346if ($phids === null) {347$rules[] = $rule;348} else if (in_array($viewer->getPHID(), $phids)) {349$rules[] = $rule;350}351}352353// Reorder rules by strength.354foreach ($rules as $key => $rule) {355$const = $rule['routingRule'];356$phids = $rule['phids'];357358if ($phids === null) {359$type = 'A';360} else {361$type = 'B';362}363364$rules[$key]['strength'] = sprintf(365'~%s%08d',366$type,367PhabricatorMailRoutingRule::getRuleStrength($const));368}369$rules = isort($rules, 'strength');370371$routing_detail = id(new PHUIStatusListView());372foreach ($rules as $rule) {373$const = $rule['routingRule'];374$phids = $rule['phids'];375376$name = PhabricatorMailRoutingRule::getRuleName($const);377378$icon = PhabricatorMailRoutingRule::getRuleIcon($const);379$color = PhabricatorMailRoutingRule::getRuleColor($const);380381if ($phids === null) {382$kind = pht('Global');383} else {384$kind = pht('Personal');385}386387$target = array($kind, ': ', $name);388$target = phutil_tag('strong', array(), $target);389390$item = id(new PHUIStatusItemView())391->setTarget($target)392->setNote($viewer->renderHandle($rule['reasonPHID']))393->setIcon($icon, $color);394395$routing_detail->addItem($item);396}397}398}399400$properties->addProperty(pht('Effective Rule'), $routing_result);401402if ($routing_detail !== null) {403$properties->addProperty(pht('All Matching Rules'), $routing_detail);404$properties->addProperty(405null,406$this->renderEmptyMessage(407pht(408'Matching rules are listed from weakest to strongest.')));409}410411return $properties;412}413414private function buildMetadataProperties(PhabricatorMetaMTAMail $mail) {415$viewer = $this->getViewer();416417$properties = id(new PHUIPropertyListView())418->setUser($viewer);419420$properties->addProperty(pht('Message PHID'), $mail->getPHID());421422$details = $mail->getMessage();423if ($details === null || !strlen($details)) {424$details = phutil_tag('em', array(), pht('None'));425}426$properties->addProperty(pht('Status Details'), $details);427428$actor_phid = $mail->getActorPHID();429if ($actor_phid) {430$actor_str = $viewer->renderHandle($actor_phid);431} else {432$actor_str = pht('Generated by Server');433}434$properties->addProperty(pht('Actor'), $actor_str);435436$related_phid = $mail->getRelatedPHID();437if ($related_phid) {438$related = $viewer->renderHandle($mail->getRelatedPHID());439} else {440$related = phutil_tag('em', array(), pht('None'));441}442$properties->addProperty(pht('Related Object'), $related);443444return $properties;445}446447private function renderEmptyMessage($message) {448return phutil_tag('em', array(), $message);449}450451}452453454