/**
  * @task mail
  */
 protected function addHeadersAndCommentsToMailBody(PhabricatorMetaMTAMailBody $body, array $xactions, $object_label = null, $object_href = null)
 {
     $headers = array();
     $headers_html = array();
     $comments = array();
     $details = array();
     foreach ($xactions as $xaction) {
         if ($xaction->shouldHideForMail($xactions)) {
             continue;
         }
         $header = $xaction->getTitleForMail();
         if ($header !== null) {
             $headers[] = $header;
         }
         $header_html = $xaction->getTitleForHTMLMail();
         if ($header_html !== null) {
             $headers_html[] = $header_html;
         }
         $comment = $xaction->getBodyForMail();
         if ($comment !== null) {
             $comments[] = $comment;
         }
         if ($xaction->hasChangeDetailsForMail()) {
             $details[] = $xaction;
         }
     }
     $headers_text = implode("\n", $headers);
     $body->addRawPlaintextSection($headers_text);
     $headers_html = phutil_implode_html(phutil_tag('br'), $headers_html);
     $header_button = null;
     if ($object_label !== null) {
         $button_style = array('text-decoration: none;', 'padding: 4px 8px;', 'margin: 0 8px 8px;', 'float: right;', 'color: #464C5C;', 'font-weight: bold;', 'border-radius: 3px;', 'background-color: #F7F7F9;', 'background-image: linear-gradient(to bottom,#fff,#f1f0f1);', 'display: inline-block;', 'border: 1px solid rgba(71,87,120,.2);');
         $header_button = phutil_tag('a', array('style' => implode(' ', $button_style), 'href' => $object_href), $object_label);
     }
     $xactions_style = array();
     $header_action = phutil_tag('td', array(), $header_button);
     $header_action = phutil_tag('td', array('style' => implode(' ', $xactions_style)), array($headers_html, "\n"));
     $headers_html = phutil_tag('table', array(), phutil_tag('tr', array(), array($header_action, $header_button)));
     $body->addRawHTMLSection($headers_html);
     foreach ($comments as $comment) {
         $body->addRemarkupSection(null, $comment);
     }
     foreach ($details as $xaction) {
         $details = $xaction->renderChangeDetailsForMail($body->getViewer());
         if ($details !== null) {
             $label = $this->getMailDiffSectionHeader($xaction);
             $body->addHTMLSection($label, $details);
         }
     }
 }
 private function appendChangeDetailsForMail(PhabricatorLiskDAO $object, DifferentialDiff $diff, $patch, PhabricatorMetaMTAMailBody $body)
 {
     $section = id(new DifferentialChangeDetailMailView())->setViewer($this->getActor())->setDiff($diff)->setPatch($patch)->buildMailSection();
     $header = pht('CHANGE DETAILS');
     $section_text = "\n" . $section->getPlaintext();
     $style = array('margin: 6px 0 12px 0;');
     $section_html = phutil_tag('div', array('style' => implode(' ', $style)), $section->getHTML());
     $body->addPlaintextSection($header, $section_text, false);
     $body->addHTMLSection($header, $section_html);
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $attachments = $mail->getAttachments();
     $files = array();
     $errors = array();
     if ($attachments) {
         $files = id(new PhabricatorFileQuery())->setViewer($sender)->withPHIDs($attachments)->execute();
         foreach ($files as $index => $file) {
             if ($file->getMimeType() != 'text/plain') {
                 $errors[] = pht('Could not parse file %s; only files with mimetype text/plain ' . 'can be parsed via email.', $file->getName());
                 unset($files[$index]);
             }
         }
     }
     $diffs = array();
     foreach ($files as $file) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $file->loadFileData()));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[$file->getName()] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse attachment %s; only attachments (and mail bodies) ' . 'generated via "diff" commands can be parsed.', $file->getName());
         }
     }
     $body = $mail->getCleanTextBody();
     if ($body) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $body));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[pht('Mail Body')] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse mail body; only mail bodies (and attachments) ' . 'generated via "diff" commands can be parsed.');
         }
     }
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix');
     if (count($diffs)) {
         $subject = pht('You successfully created %d diff(s).', count($diffs));
     } else {
         $subject = pht('Diff creation failed; see body for %s error(s).', new PhutilNumber(count($errors)));
     }
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     if (count($diffs)) {
         $text_body = '';
         $html_body = array();
         $body_label = pht('%s DIFF LINK(S)', new PhutilNumber(count($diffs)));
         foreach ($diffs as $filename => $diff_uri) {
             $text_body .= $filename . ': ' . $diff_uri . "\n";
             $html_body[] = phutil_tag('a', array('href' => $diff_uri), $filename);
             $html_body[] = phutil_tag('br');
         }
         $body->addTextSection($body_label, $text_body);
         $body->addHTMLSection($body_label, $html_body);
     }
     if (count($errors)) {
         $body_section = new PhabricatorMetaMTAMailSection();
         $body_label = pht('%s ERROR(S)', new PhutilNumber(count($errors)));
         foreach ($errors as $error) {
             $body_section->addFragment($error);
         }
         $body->addTextSection($body_label, $body_section);
     }
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setBody($body->render())->saveAndSend();
 }