Seb35 has uploaded a new change for review. https://gerrit.wikimedia.org/r/236417
Change subject: Phabricator extension to add links on Bugzilla "bug NNN" syntax ...................................................................... Phabricator extension to add links on Bugzilla "bug NNN" syntax DO NOT MERGE - SUPER HACKY - see inside Added a custom inline rule, which converts "bug NNN" to links to the corresponding task in Phabricator (with a shift of 2000 for Wikimedia). The non-hacky part do work in contexts where there is only one parsing engines (e.g. when previewing a comment) but is mandatory when there are many parsing engines (e.g. displaying a complete page). Bug: T687 Change-Id: I0a78ab0418df4219d9413de965854d97936233de --- A PhabricatorBugzillaRemarkupRule.php 1 file changed, 168 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/phabricator/extensions refs/changes/17/236417/1 diff --git a/PhabricatorBugzillaRemarkupRule.php b/PhabricatorBugzillaRemarkupRule.php new file mode 100644 index 0000000..afbcb87 --- /dev/null +++ b/PhabricatorBugzillaRemarkupRule.php @@ -0,0 +1,168 @@ +<?php + +// A Phabricator extension to convert syntax "bug NNN" (from Bugzilla) to task links +// Licence: WTFPL 2.0 +// Author: Seb35 + +final class PhabricatorBugzillaRemarkupRule extends PhabricatorRemarkupCustomInlineRule { + + // HACKY HACKY HACKY + // + // Without this, you can observe an exception in $this->getEngine()->storeText() + // when you have the text "bug 1" in the main description in Maniphest + // + // It happens PhabricatorRemarkupCustomInlineRule instances got another + // PhutilRemarkupEngine instance because two instances seems to be created + // (for main description and comments in Maniphest) and, contrary to other + // PhutilRemarkupRule instances, the engine for this rule could be overwritten + // by another engine (e.g. the comment engines used to parse main description). + // Since the engines are not correctly mapped to their use, all engines are + // saved here and it is later used the "correct" engine, i.e. the one which + // doesn’t trigger an Error, corresponding to an attempt to execute + // "$this->storage->store()" in PhutilRemarkupEngine::storeText() where + // the "storage" property is not set (only set on the active engine). + // + // Note that functions have to be used here since the property $this->engine + // is private + // + // Not sure if it is a Phabricator upstream bug or if I misuse Remarkup + // custom rules (anyhow it is not documented) + + private $engines = array(); + + public function setEngine(PhutilRemarkupEngine $engine) { + PhutilRemarkupRule::setEngine($engine); + $this->engines[] =& $engine; + return $this; + } + + // END HACKY - but some remainings in markupBugzilla() + + + public function getPriority() { + return 450; + } + + public function apply($text) { + if ($this->getEngine()->isTextMode()) { + return $text; + } + + $text = preg_replace_callback( + '@[Bb]ug #?([1-9]\d*)@m', + array($this, 'markupBugzilla'), + $text); + + return $text; + } + + protected function markupBugzilla(array $matches) { + if (!$this->isFlatText($matches[0])) { + return $matches[0]; + } + + // Get context + $mail_mode = $this->getEngine()->isHTMLMailMode(); + $status_closed = PhabricatorObjectHandle::STATUS_CLOSED; + + // Parameters and results + $text = $matches[0]; + $id = $matches[1]+2000; // there is a shift of 2000 between Bugzilla and Phabricator for Wikimedia + $attr = array(); + $href = ''; + + // Get URL and metadata + $objects = $this->loadObjects(array($id)); + $handle = $this->loadHandles($objects)[1]; + if( !is_null($handle) ) { + $href = $this->getObjectHref($objects[1], $handle, $id); + $attr = array( + 'phid' => $handle->getPHID(), + 'closed' => ($handle->getStatus() == $status_closed), + ); + } + + // Depending on the context, add more or less information about the task + if( !$href ) return $text; + $link = $text; + if ($mail_mode) { + $link = phutil_tag( + 'a', + array( + 'href' => $href + ), + $text); + } + else { + $link = $this->renderHovertag($text, $href, $attr); + } + + // HACKY HACKY HACKY - see above + $origEngine = $this->getEngine(); + foreach( $this->engines as $engine ) { + PhutilRemarkupRule::setEngine($engine); + try { + $token = $this->getEngine()->storeText($link); + } + catch(Error $e) { + continue; + } + } + PhutilRemarkupRule::setEngine($origEngine); + // END HACKY + + return $token; + } + + // Copied from PhabricatorObjectRemarkupRule + protected function loadObjects(array $ids) { + $viewer = $this->getEngine()->getConfig('viewer'); + + return id(new ManiphestTaskQuery()) + ->setViewer($viewer) + ->withIDs($ids) + ->execute(); + } + + // Copied from PhabricatorObjectRemarkupRule + protected function loadHandles(array $objects) { + $phids = mpull($objects, 'getPHID'); + + $viewer = $this->getEngine()->getConfig('viewer'); + $handles = $viewer->loadHandles($phids); + $handles = iterator_to_array($handles); + + $result = array(); + foreach ($objects as $id => $object) { + $result[$id] = $handles[$object->getPHID()]; + } + return $result; + } + + // Copied from PhabricatorObjectRemarkupRule + protected function getObjectHref( + $object, + PhabricatorObjectHandle $handle, + $id) { + + $uri = $handle->getURI(); + + if ($this->getEngine()->getConfig('uri.full')) { + $uri = PhabricatorEnv::getURI($uri); + } + + return $uri; + } + + // Copied from PhabricatorObjectRemarkupRule + protected function renderHovertag($name, $href, array $attr = array()) { + return id(new PHUITagView()) + ->setName($name) + ->setHref($href) + ->setType(PHUITagView::TYPE_OBJECT) + ->setPHID(idx($attr, 'phid')) + ->setClosed(idx($attr, 'closed')) + ->render(); + } +} + -- To view, visit https://gerrit.wikimedia.org/r/236417 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0a78ab0418df4219d9413de965854d97936233de Gerrit-PatchSet: 1 Gerrit-Project: phabricator/extensions Gerrit-Branch: master Gerrit-Owner: Seb35 <seb35wikipe...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits