From bfdc9411f705cc47ad15e128e15b2c7f959715cb Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 16 Feb 2018 04:58:46 -0800 Subject: [PATCH] Provide context objects for remarkup mail rendering, fixing Phriction relative URIs in initial email Summary: Fixes T10969. Ref T13077. When you create a Phriction document with a relative link (`[[ ./path/to/page ]]`) the initial email currently points to the wrong place. This is because the context object (the page) isn't passed to the markup engine. Without this context, the relative link is rendered as though it appeared somewhere else (like a task or revision) where relative links don't make sense. Test Plan: Created a new Phriction document with a relative link to `[[ ./porcupine_facts/starmap ]]`, saw a usable link in the resulting email. Maniphest Tasks: T13077, T10969 Differential Revision: https://secure.phabricator.com/D19105 --- .../view/PhabricatorMetaMTAMailBody.php | 41 +++++++++++++++---- .../markup/PhrictionRemarkupRule.php | 38 ++++++++++++----- ...habricatorApplicationTransactionEditor.php | 6 ++- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php b/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php index 8a21a75cfb..6aaf4fb052 100644 --- a/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php +++ b/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php @@ -13,6 +13,7 @@ final class PhabricatorMetaMTAMailBody extends Phobject { private $attachments = array(); private $viewer; + private $contextObject; public function getViewer() { return $this->viewer; @@ -23,6 +24,16 @@ final class PhabricatorMetaMTAMailBody extends Phobject { return $this; } + public function setContextObject($context_object) { + $this->contextObject = $context_object; + return $this; + } + + public function getContextObject() { + return $this->contextObject; + } + + /* -( Composition )-------------------------------------------------------- */ @@ -45,9 +56,9 @@ final class PhabricatorMetaMTAMailBody extends Phobject { public function addRemarkupSection($header, $text) { try { - $engine = PhabricatorMarkupEngine::newMarkupEngine(array()); - $engine->setConfig('viewer', $this->getViewer()); - $engine->setMode(PhutilRemarkupEngine::MODE_TEXT); + $engine = $this->newMarkupEngine() + ->setMode(PhutilRemarkupEngine::MODE_TEXT); + $styled_text = $engine->markupText($text); $this->addPlaintextSection($header, $styled_text); } catch (Exception $ex) { @@ -56,12 +67,9 @@ final class PhabricatorMetaMTAMailBody extends Phobject { } try { - $mail_engine = PhabricatorMarkupEngine::newMarkupEngine(array()); - $mail_engine->setConfig('viewer', $this->getViewer()); - $mail_engine->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL); - $mail_engine->setConfig( - 'uri.base', - PhabricatorEnv::getProductionURI('/')); + $mail_engine = $this->newMarkupEngine() + ->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL); + $html = $mail_engine->markupText($text); $this->addHTMLSection($header, $html); } catch (Exception $ex) { @@ -215,4 +223,19 @@ final class PhabricatorMetaMTAMailBody extends Phobject { private function indent($text) { return rtrim(" ".str_replace("\n", "\n ", $text)); } + + + private function newMarkupEngine() { + $engine = PhabricatorMarkupEngine::newMarkupEngine(array()) + ->setConfig('viewer', $this->getViewer()) + ->setConfig('uri.base', PhabricatorEnv::getProductionURI('/')); + + $context = $this->getContextObject(); + if ($context) { + $engine->setConfig('contextObject', $context); + } + + return $engine; + } + } diff --git a/src/applications/phriction/markup/PhrictionRemarkupRule.php b/src/applications/phriction/markup/PhrictionRemarkupRule.php index 9c5649bbbe..c4bc1f7249 100644 --- a/src/applications/phriction/markup/PhrictionRemarkupRule.php +++ b/src/applications/phriction/markup/PhrictionRemarkupRule.php @@ -28,17 +28,7 @@ final class PhrictionRemarkupRule extends PhutilRemarkupRule { // Handle relative links. if ((substr($link, 0, 2) === './') || (substr($link, 0, 3) === '../')) { - $base = null; - $context = $this->getEngine()->getConfig('contextObject'); - if ($context !== null && $context instanceof PhrictionContent) { - // Handle content when it's being rendered in document view. - $base = $context->getSlug(); - } - if ($context !== null && is_array($context) && - idx($context, 'phriction.isPreview')) { - // Handle content when it's a preview for the Phriction editor. - $base = idx($context, 'phriction.slug'); - } + $base = $this->getRelativeBaseURI(); if ($base !== null) { $base_parts = explode('/', rtrim($base, '/')); $rel_parts = explode('/', rtrim($link, '/')); @@ -195,4 +185,30 @@ final class PhrictionRemarkupRule extends PhutilRemarkupRule { } } + private function getRelativeBaseURI() { + $context = $this->getEngine()->getConfig('contextObject'); + + if (!$context) { + return null; + } + + // Handle content when it's a preview for the Phriction editor. + if (is_array($context)) { + if (idx($context, 'phriction.isPreview')) { + return idx($context, 'phriction.slug'); + } + } + + if ($context instanceof PhrictionContent) { + return $context->getSlug(); + } + + if ($context instanceof PhrictionDocument) { + return $context->getSlug(); + } + + return null; + } + + } diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 7cb1300feb..1d02d0fdb0 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -2880,11 +2880,13 @@ abstract class PhabricatorApplicationTransactionEditor PhabricatorLiskDAO $object, array $xactions) { - $body = new PhabricatorMetaMTAMailBody(); - $body->setViewer($this->requireActor()); + $body = id(new PhabricatorMetaMTAMailBody()) + ->setViewer($this->requireActor()) + ->setContextObject($object); $this->addHeadersAndCommentsToMailBody($body, $xactions); $this->addCustomFieldsToMailBody($body, $object, $xactions); + return $body; }