</attribute>
</attributes>
</bbcode>
+
+ <bbcode name="user">
+ <classname>wcf\system\bbcode\UserBBCode</classname>
+ <attributes>
+ <attribute name="0">
+ <validationpattern>^\d+$</validationpattern>
+ <required>1</required>
+ </attribute>
+ </attributes>
+ </bbcode>
</import>
</data>
<definitionname>com.woltlab.wcf.message.embeddedObject</definitionname>
<classname>wcf\system\message\embedded\object\MediaMessageEmbeddedObjectHandler</classname>
</type>
+ <type>
+ <name>com.woltlab.wcf.user</name>
+ <definitionname>com.woltlab.wcf.message.embeddedObject</definitionname>
+ <classname>wcf\system\message\embedded\object\UserMessageEmbeddedObjectHandler</classname>
+ </type>
<!-- embedded object handlers -->
<type>
+++ /dev/null
-{if $userProfile === null}
- {* user no longer exists, use plain output rather than using a broken link *}
- @{$username}
-{else}
- {* non-breaking space below to prevent wrapping of user avatar and username *}
- <a href="{link controller='User' object=$userProfile->getDecoratedObject()}{/link}">{@$userProfile->getAvatar()->getImageTag(16)} {$userProfile->username}</a>
-{/if}
\ No newline at end of file
--- /dev/null
+{if $userProfile === null}
+ {* user no longer exists, use plain output rather than using a broken link *}
+ @{$username}
+{else}
+ {* non-breaking space below to prevent wrapping of user avatar and username *}
+ <a href="{link controller='User' object=$userProfile->getDecoratedObject()}{/link}">{@$userProfile->getAvatar()->getImageTag(16)} {$userProfile->username}</a>
+{/if}
-<style>
- woltlab-mention {
- background-color: rgb(241, 246, 251);
- border: 1px solid rgb(176, 200, 224);
- border-radius: 2px;
- display: inline-block;
- margin: 0 3px;
- padding: 0 2px;
- }
-
- woltlab-mention::before {
- color: rgb(125, 130, 135);
- content: "@";
- padding-right: 2px;
- }
-
- woltlab-mention::after {
- color: rgb(44, 62, 80);
- content: attr(data-username);
- }
-</style>
-
<script data-relocate="true">
head.load([
{if ENABLE_DEBUG_MODE}
-<style>
- woltlab-mention {
- background-color: rgb(240, 248, 255);
- border: 1px solid rgb(52, 152, 219);
- display: inline-block;
- margin: 0 3px;
- padding: 0 2px;
- }
-</style>
-
<script data-relocate="true">
head.load([
{if ENABLE_DEBUG_MODE}
return {
init: function() {
- //var WoltLabMention = document.registerElement('woltlab-mention');
-
require(['WoltLabSuite/Core/Ui/Redactor/Mention'], (function(UiRedactorMention) {
new UiRedactorMention(this);
}).bind(this));
range.deleteContents();
range.collapse(true);
- var mention = elCreate('woltlab-mention');
- elAttr(mention, 'contenteditable', 'false');
- elData(mention, 'user-id', elData(item, 'user-id'));
- elData(mention, 'username', elData(item, 'username'));
-
- // U+200C = zero width non-joiner
- var text = document.createTextNode('\u200c');
-
+ var text = document.createTextNode('@' + elData(item, 'username') + '\u00A0');
range.insertNode(text);
- range.insertNode(mention);
newRange = document.createRange();
newRange.selectNode(text);
--- /dev/null
+<?php
+namespace wcf\system\bbcode;
+use wcf\data\user\UserProfile;
+use wcf\system\message\embedded\object\MessageEmbeddedObjectManager;
+use wcf\system\WCF;
+
+/**
+ * Parses the [user] bbcode tag.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Bbcode
+ * @since 3.0
+ */
+class UserBBCode extends AbstractBBCode {
+ /**
+ * @inheritDoc
+ */
+ public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) {
+ $userID = (!empty($openingTag['attributes'][0])) ? intval($openingTag['attributes'][0]) : 0;
+ if (!$userID) {
+ return "[user]{$content}[/user]";
+ }
+
+ /** @var UserProfile $userProfile */
+ $userProfile = MessageEmbeddedObjectManager::getInstance()->getObject('com.woltlab.wcf.user', $userID);
+ if ($userProfile === null) {
+ return '@'.$content;
+ }
+
+ return WCF::getTPL()->fetch('userBBCodeTag', 'wcf', [
+ 'username' => $content,
+ 'userProfile' => $userProfile
+ ], true);
+ }
+}
$definition->addAttribute('img', 'data-media-id', 'Number');
$definition->addAttribute('img', 'data-media-size', new \HTMLPurifier_AttrDef_Enum(['small', 'medium', 'large', 'original']));
- // mention
- $definition->addElement('woltlab-mention', 'Inline', 'Inline', '', [
- 'data-user-id' => 'Number',
- 'data-username' => 'Text'
- ]);
-
// spoiler
$definition->addElement('woltlab-spoiler', 'Block', 'Flow', '', [
'data-label' => 'Text'
use wcf\system\bbcode\HtmlBBCodeParser;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\WCF;
+use wcf\util\JSON;
use wcf\util\StringUtil;
/**
}
if ($pos !== false) {
- $element = $text->ownerDocument->createElement('woltlab-mention');
- $element->setAttribute('data-user-id', $userID);
- $element->setAttribute('data-username', $username);
+ $element = $text->ownerDocument->createElement('woltlab-metacode');
+ $element->setAttribute('data-name', 'user');
+ $element->setAttribute('data-attributes', base64_encode(JSON::encode([$userID])));
+ $element->appendChild($text->ownerDocument->createTextNode($username));
$marker = $this->addReplacement($text, $element);
+++ /dev/null
-<?php
-namespace wcf\system\html\input\node;
-use wcf\system\html\node\AbstractHtmlNodeProcessor;
-
-/**
- * Processes `<woltlab-mention>`.
- *
- * @author Alexander Ebert
- * @copyright 2001-2016 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Html\Input\Node
- * @since 3.0
- */
-class HtmlInputNodeWoltlabMention extends AbstractHtmlInputNode {
- /**
- * @inheritDoc
- */
- protected $tagName = 'woltlab-mention';
-
- /**
- * @inheritDoc
- */
- public function isAllowed(AbstractHtmlNodeProcessor $htmlNodeProcessor) {
- // mentions are always allowed
- return [];
- }
-
- /**
- * @inheritDoc
- */
- public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) {
- // TODO
-
- $userIds = [];
-
- /** @var \DOMElement $mention */
- foreach ($elements as $mention) {
- $userId = intval($mention->getAttribute('data-user-id'));
- if ($userId) {
- $userIds[] = $userId;
- }
- }
-
- if (!empty($userIds)) {
-
- }
- }
-}
+++ /dev/null
-<?php
-namespace wcf\system\html\output\node;
-use wcf\data\user\UserProfile;
-use wcf\system\cache\runtime\UserProfileRuntimeCache;
-use wcf\system\html\node\AbstractHtmlNodeProcessor;
-use wcf\system\WCF;
-use wcf\util\DOMUtil;
-use wcf\util\StringUtil;
-
-/**
- * Processes user mentions.
- *
- * @author Alexander Ebert
- * @copyright 2001-2016 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Html\Output\Node
- * @since 3.0
- */
-class HtmlOutputNodeWoltlabMention extends AbstractHtmlOutputNode {
- /**
- * @inheritDoc
- */
- protected $tagName = 'woltlab-mention';
-
- /**
- * @var UserProfile[]
- */
- protected $userProfiles;
-
- /**
- * @inheritDoc
- */
- public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) {
- if ($this->outputType === 'text/html' || $this->outputType === 'text/simplified-html') {
- $this->userProfiles = [];
-
- $userIds = [];
- /** @var \DOMElement $element */
- foreach ($elements as $element) {
- $userId = intval($element->getAttribute('data-user-id'));
- $username = StringUtil::trim($element->getAttribute('data-username'));
-
- if ($userId === 0 || $username === '') {
- DOMUtil::removeNode($element);
- continue;
- }
-
- $userIds[] = $userId;
- $nodeIdentifier = StringUtil::getRandomID();
- $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, ['userId' => $userId, 'username' => $username]);
-
- $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
- }
-
- if (!empty($userIds)) {
- $this->userProfiles = UserProfileRuntimeCache::getInstance()->getObjects($userIds);
- }
- }
- else if ($this->outputType === 'text/plain') {
- /** @var \DOMElement $element */
- foreach ($elements as $element) {
- $htmlNodeProcessor->replaceElementWithText($element, '@' . $element->getAttribute('data-username'), false);
- }
- }
- }
-
- /**
- * @inheritDoc
- */
- public function replaceTag(array $data) {
- WCF::getTPL()->assign([
- 'username' => $data['username'],
- 'userId' => $data['userId'],
- 'userProfile' => $this->userProfiles[$data['userId']]
- ]);
-
- return WCF::getTPL()->fetch('htmlNodeWoltlabMention');
- }
-}
--- /dev/null
+<?php
+namespace wcf\system\message\embedded\object;
+use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\html\input\HtmlInputProcessor;
+
+/**
+ * Parses embedded users.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Message\Embedded\Object
+ */
+class UserMessageEmbeddedObjectHandler extends AbstractMessageEmbeddedObjectHandler {
+ /**
+ * @inheritDoc
+ */
+ public function parse(HtmlInputProcessor $htmlInputProcessor, array $embeddedData) {
+ $objectIDs = [];
+ if (!empty($embeddedData['user'])) {
+ for ($i = 0, $length = count($embeddedData['user']); $i < $length; $i++) {
+ $objectIDs[] = intval($embeddedData['user'][$i][0]);
+ }
+ }
+
+ return array_unique($objectIDs);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function loadObjects(array $objectIDs) {
+ return UserProfileRuntimeCache::getInstance()->getObjects($objectIDs);
+ }
+}
* list of bbcode tags that are always available
* @var string[]
*/
- protected static $alwaysAvailable = ['align', 'attach', 'b', 'code', 'i', 'list', 'quote', 's', 'sub', 'sup', 'table', 'td', 'tr', 'tt', 'u', 'wsm', 'wsmg', 'wsp'];
+ protected static $alwaysAvailable = ['align', 'attach', 'b', 'code', 'i', 'list', 'quote', 's', 'sub', 'sup', 'table', 'td', 'tr', 'tt', 'u', 'user', 'wsm', 'wsmg', 'wsp'];
/**
* @inheritDoc
public static function getMentionedUsers(HtmlInputProcessor $htmlInputProcessor) {
$usernames = [];
- $elements = $htmlInputProcessor->getHtmlInputNodeProcessor()->getDocument()->getElementsByTagName('woltlab-mention');
+ $elements = $htmlInputProcessor->getHtmlInputNodeProcessor()->getDocument()->getElementsByTagName('woltlab-metacode');
/** @var \DOMElement $element */
foreach ($elements as $element) {
+ if ($element->getAttribute('data-name') != 'user') {
+ continue;
+ }
+
if (DOMUtil::hasParent($element, 'blockquote')) {
// ignore mentions within quotes
continue;
}
- $usernames[] = $element->getAttribute('data-username');
+ $usernames[] = $element->textContent;
}
return $usernames;