From 13825b39515f7d2ee48e9f835bd475e408f09357 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 11 Oct 2017 14:34:32 +0200 Subject: [PATCH] Added improved message reprocessing API Closes #2438 --- .../html/input/HtmlInputProcessor.class.php | 37 +++++++++++++++++++ .../worker/CommentRebuildDataWorker.class.php | 4 ++ .../worker/PageRebuildDataWorker.class.php | 15 +++++++- .../worker/UserRebuildDataWorker.class.php | 37 +++++++++++-------- 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php index 56b3121ce4..c9ca11b7ce 100644 --- a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php @@ -5,6 +5,7 @@ use wcf\system\html\input\filter\IHtmlInputFilter; use wcf\system\html\input\filter\MessageHtmlInputFilter; use wcf\system\html\input\node\HtmlInputNodeProcessor; use wcf\system\html\AbstractHtmlProcessor; +use wcf\util\DOMUtil; use wcf\util\StringUtil; /** @@ -77,6 +78,42 @@ class HtmlInputProcessor extends AbstractHtmlProcessor { $this->getHtmlInputNodeProcessor()->load($this, $html); } + /** + * Reprocesses a message by transforming the message into an editor-like + * state using plain bbcodes instead of metacode elements. + * + * @param string $html html string + * @param string $objectType object type identifier + * @param integer $objectID object id + * @since 3.1 + */ + public function reprocess($html, $objectType, $objectID) { + $this->processIntermediate($html); + + // revert embedded bbcodes for re-evaluation + $metacodes = DOMUtil::getElements($this->getHtmlInputNodeProcessor()->getDocument(), 'woltlab-metacode'); + foreach ($metacodes as $metacode) { + $name = $metacode->getAttribute('data-name'); + $attributes = $this->getHtmlInputNodeProcessor()->parseAttributes($metacode->getAttribute('data-attributes')); + + $bbcodeAttributes = ''; + foreach ($attributes as $attribute) { + if (!empty($bbcodeAttributes)) $bbcodeAttributes .= ','; + $bbcodeAttributes .= "'" . addcslashes($attribute, "'") . "'"; + } + + $text = $metacode->ownerDocument->createTextNode('[' . $name . (!empty($bbcodeAttributes) ? '=' . $bbcodeAttributes : '') . ']'); + $metacode->insertBefore($text, $metacode->firstChild); + + $text = $metacode->ownerDocument->createTextNode('[/' . $name . ']'); + $metacode->appendChild($text); + + DOMUtil::removeNode($metacode, true); + } + + $this->process($html, $objectType, $objectID, false); + } + /** * Processes only embedded content. This method should only be called when rebuilding * data where only embedded content is relevant, but no actual parsing is required. diff --git a/wcfsetup/install/files/lib/system/worker/CommentRebuildDataWorker.class.php b/wcfsetup/install/files/lib/system/worker/CommentRebuildDataWorker.class.php index f374d7517b..7d10a017d0 100644 --- a/wcfsetup/install/files/lib/system/worker/CommentRebuildDataWorker.class.php +++ b/wcfsetup/install/files/lib/system/worker/CommentRebuildDataWorker.class.php @@ -79,6 +79,10 @@ class CommentRebuildDataWorker extends AbstractRebuildDataWorker { 'enableHtml' => 1 ]); } + else { + $this->getHtmlInputProcessor()->reprocess($comment->message, 'com.woltlab.wcf.comment', $comment->commentID); + $commentEditor->update(['message' => $this->getHtmlInputProcessor()->getHtml()]); + } } WCF::getDB()->commitTransaction(); } diff --git a/wcfsetup/install/files/lib/system/worker/PageRebuildDataWorker.class.php b/wcfsetup/install/files/lib/system/worker/PageRebuildDataWorker.class.php index abd669fed0..d0aedd9dc7 100644 --- a/wcfsetup/install/files/lib/system/worker/PageRebuildDataWorker.class.php +++ b/wcfsetup/install/files/lib/system/worker/PageRebuildDataWorker.class.php @@ -81,7 +81,14 @@ class PageRebuildDataWorker extends AbstractRebuildDataWorker { } // update embedded objects - $this->getHtmlInputProcessor()->processEmbeddedContent($pageContent->content, 'com.woltlab.wcf.page.content', $pageContent->pageContentID); + $data = []; + if ($page->pageType == 'text') { + $this->getHtmlInputProcessor()->process($pageContent->content, 'com.woltlab.wcf.page.content', $pageContent->pageContentID); + $data['content'] = $this->getHtmlInputProcessor()->getHtml(); + } + else { + $this->getHtmlInputProcessor()->processEmbeddedContent($pageContent->content, 'com.woltlab.wcf.page.content', $pageContent->pageContentID); + } $hasEmbeddedObjects = 0; if (MessageEmbeddedObjectManager::getInstance()->registerObjects($this->getHtmlInputProcessor())) { @@ -89,8 +96,12 @@ class PageRebuildDataWorker extends AbstractRebuildDataWorker { } if ($hasEmbeddedObjects != $pageContent->hasEmbeddedObjects) { + $data['hasEmbeddedObjects'] = $hasEmbeddedObjects; + } + + if (!empty($data)) { $pageContentEditor = new PageContentEditor($pageContent); - $pageContentEditor->update(['hasEmbeddedObjects' => $hasEmbeddedObjects]); + $pageContentEditor->update($data); } } } diff --git a/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php b/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php index 7ecb4c3da5..55fdc31ad4 100644 --- a/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php +++ b/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php @@ -121,23 +121,30 @@ class UserRebuildDataWorker extends AbstractRebuildDataWorker { 'signature' => $htmlInputProcessor->getHtml(), 'signatureEnableHtml' => 1 ]); - - if ($user->aboutMe) { + } + else { + $htmlInputProcessor->reprocess($user->signature, 'com.woltlab.wcf.user.signature', $user->userID); + $user->update(['signature' => $htmlInputProcessor->getHtml()]); + } + + if ($user->aboutMe) { + if (!$user->signatureEnableHtml) { $htmlInputProcessor->process($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID, true); - $html = $htmlInputProcessor->getHtml(); - // MySQL's TEXT type allows for 65,535 bytes, hence we need to count - // the bytes rather than the actual amount of characters - if (strlen($html) > 65535) { - // content does not fit the available space, and any - // attempts to truncate it will yield awkward results - $html = ''; - } - - $statement->execute([ - $html, - $user->userID - ]); } + else { + $htmlInputProcessor->reprocess($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID); + } + + $html = $htmlInputProcessor->getHtml(); + // MySQL's TEXT type allows for 65,535 bytes, hence we need to count + // the bytes rather than the actual amount of characters + if (strlen($html) > 65535) { + // content does not fit the available space, and any + // attempts to truncate it will yield awkward results + $html = ''; + } + + $statement->execute([$html, $user->userID]); } } WCF::getDB()->commitTransaction(); -- 2.20.1