Added improved message reprocessing API
authorAlexander Ebert <ebert@woltlab.com>
Wed, 11 Oct 2017 12:34:32 +0000 (14:34 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 11 Oct 2017 12:34:32 +0000 (14:34 +0200)
Closes #2438

wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php
wcfsetup/install/files/lib/system/worker/CommentRebuildDataWorker.class.php
wcfsetup/install/files/lib/system/worker/PageRebuildDataWorker.class.php
wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php

index 56b3121ce410aae5f1797aa3e5513a1e52543ff2..c9ca11b7cefbaa939d1ac4440a2343d53b9e759f 100644 (file)
@@ -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.
index f374d7517bc62b342487ec0fe05a9d810078946c..7d10a017d008b4e8cceb03e3fd55d8e0337b6846 100644 (file)
@@ -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();
        }
index abd669fed0bacbcbd569199eb573e460951293fa..d0aedd9dc7b3b7fdb6cf1d0cc8fb26f4725021dd 100644 (file)
@@ -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);
                        }
                }
        }
index 7ecb4c3da50984ba317af9127b0faef3d59746e9..55fdc31ad4a1eb696c8063e93205d2337d04c98a 100644 (file)
@@ -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();