private function renderInlineCommentsForMail(PhabricatorLiskDAO $object, array $inlines) { $context_key = 'metamta.differential.unified-comment-context'; $show_context = PhabricatorEnv::getEnvConfig($context_key); $changeset_ids = array(); $line_numbers_by_changeset = array(); foreach ($inlines as $inline) { $id = $inline->getComment()->getChangesetID(); $changeset_ids[$id] = $id; $line_numbers_by_changeset[$id][] = $inline->getComment()->getLineNumber(); } $changesets = id(new DifferentialChangesetQuery())->setViewer($this->getActor())->withIDs($changeset_ids)->needHunks(true)->execute(); $inline_groups = DifferentialTransactionComment::sortAndGroupInlines($inlines, $changesets); if ($show_context) { $hunk_parser = new DifferentialHunkParser(); $table = new DifferentialTransactionComment(); $conn_r = $table->establishConnection('r'); $queries = array(); foreach ($line_numbers_by_changeset as $id => $line_numbers) { $queries[] = qsprintf($conn_r, '(changesetID = %d AND lineNumber IN (%Ld))', $id, $line_numbers); } $all_comments = id(new DifferentialTransactionComment())->loadAllWhere('transactionPHID IS NOT NULL AND (%Q)', implode(' OR ', $queries)); $comments_by_line_number = array(); foreach ($all_comments as $comment) { $comments_by_line_number[$comment->getChangesetID()][$comment->getLineNumber()][$comment->getID()] = $comment; } $author_phids = mpull($all_comments, 'getAuthorPHID'); $authors = id(new PhabricatorPeopleQuery())->setViewer($this->getActor())->withPHIDs($author_phids)->execute(); $authors_by_phid = mpull($authors, null, 'getPHID'); } $section = new PhabricatorMetaMTAMailSection(); foreach ($inline_groups as $changeset_id => $group) { $changeset = idx($changesets, $changeset_id); if (!$changeset) { continue; } foreach ($group as $inline) { $comment = $inline->getComment(); $file = $changeset->getFilename(); $start = $comment->getLineNumber(); $len = $comment->getLineLength(); if ($len) { $range = $start . '-' . ($start + $len); } else { $range = $start; } $inline_content = $comment->getContent(); if (!$show_context) { $section->addFragment("{$file}:{$range} {$inline_content}"); } else { $patch = $hunk_parser->makeContextDiff($changeset->getHunks(), $comment->getIsNewFile(), $comment->getLineNumber(), $comment->getLineLength(), 1); $nested_comments = $this->nestCommentHistory($inline->getComment(), $comments_by_line_number, $authors_by_phid); $section->addFragment('================')->addFragment(pht('Comment at: %s:%s', $file, $range))->addPlaintextFragment($patch)->addHTMLFragment($this->renderPatchHTMLForMail($patch))->addFragment('----------------')->addFragment($nested_comments)->addFragment(null); } } } return $section; }
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(); }