Disables parsing of mentions in quotes
authorMatthias Schmidt <gravatronics@live.com>
Tue, 20 Aug 2013 13:12:50 +0000 (15:12 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Tue, 20 Aug 2013 13:12:50 +0000 (15:12 +0200)
wcfsetup/install/files/lib/system/event/listener/PreParserAtUserListener.class.php

index 177b5616fedcbcb564927b006236531a23f267c8..94e6a1ff8ed7b906ce2635cd1eb7803cfca2a576 100644 (file)
@@ -6,6 +6,7 @@ use wcf\system\event\IEventListener;
 use wcf\system\request\LinkHandler;
 use wcf\system\Callback;
 use wcf\system\Regex;
+use wcf\util\StringStack;
 use wcf\util\StringUtil;
 
 /**
@@ -35,7 +36,39 @@ class PreParserAtUserListener implements IEventListener {
                        $userRegex = new Regex("(?<=^|\s)@([^',\s][^,\s]{2,}|'(?:''|[^'])*')");
                }
                
-               $userRegex->match($eventObj->text, true);
+               // cache quotes
+               // @see wcf\system\bbcode\BBCodeParser::buildTagArray()
+               $pattern = '~\[(?:/(?:quote)|(?:quote)
+                       (?:=
+                               (?:\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^,\]]*)
+                               (?:,(?:\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^,\]]*))*
+                       )?)\]~ix';
+               preg_match_all($pattern, $eventObj->text, $quoteMatches);
+               $textArray = preg_split($pattern, $eventObj->text);
+               $text = $textArray[0];
+               
+               $openQuotes = 0;
+               $quote = '';
+               foreach ($quoteMatches[0] as $i => $quoteTag) {
+                       if (mb_substr($quoteTag, 1, 1) == '/') {
+                               $openQuotes--;
+                               
+                               $quote .= $quoteTag;
+                               if ($openQuotes) {
+                                       $quote .= $textArray[$i + 1];
+                               }
+                               else {
+                                       $text .= StringStack::pushToStringStack($quote, 'preParserUserMentions', '@@@').$textArray[$i + 1];
+                                       $quote = '';
+                               }
+                       }
+                       else {
+                               $openQuotes++;
+                               $quote .= $quoteTag.$textArray[$i + 1];
+                       }
+               }
+               
+               $userRegex->match($text, true);
                $matches = $userRegex->getMatches();
                
                if (!empty($matches[1])) {
@@ -55,7 +88,7 @@ class PreParserAtUserListener implements IEventListener {
                                        $users[StringUtil::toLowerCase($user->username)] = $user; 
                                }
                                
-                               $eventObj->text = $userRegex->replace($eventObj->text, new Callback(function ($matches) use ($users) {
+                               $text = $userRegex->replace($text, new Callback(function ($matches) use ($users) {
                                        $username = PreParserAtUserListener::getUsername($matches[1]);
                                        
                                        if (isset($users[$username])) {
@@ -69,6 +102,9 @@ class PreParserAtUserListener implements IEventListener {
                                }));
                        }
                }
+               
+               // reinsert cached quotes
+               $eventObj->text = StringStack::reinsertStrings($text, 'preParserUserMentions');
        }
        
        /**