From 8031a1a1dd686e050a7d1f4b37fb3aad795e4c0a Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sat, 28 May 2016 19:11:27 +0200 Subject: [PATCH] Added support for embedded objects --- com.woltlab.wcf/bbcode.xml | 3 +- .../system/bbcode/AttachmentBBCode.class.php | 28 ++++++----- .../input/node/HtmlInputNodeImg.class.php | 16 +++++- ...ractMessageEmbeddedObjectHandler.class.php | 49 ++----------------- ...mentMessageEmbeddedObjectHandler.class.php | 35 +++++++------ .../IMessageEmbeddedObjectHandler.class.php | 13 +++-- .../MessageEmbeddedObjectManager.class.php | 24 +++++---- wcfsetup/install/files/style/ui/message.scss | 4 ++ 8 files changed, 85 insertions(+), 87 deletions(-) diff --git a/com.woltlab.wcf/bbcode.xml b/com.woltlab.wcf/bbcode.xml index 5927a02661..a74e295ffb 100644 --- a/com.woltlab.wcf/bbcode.xml +++ b/com.woltlab.wcf/bbcode.xml @@ -175,7 +175,8 @@ ^(left|right|none)$ - ^\d+$ + + ^(\d+|true|false)$ diff --git a/wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php b/wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php index cc3733bb20..cde73c7290 100644 --- a/wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php +++ b/wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php @@ -58,22 +58,28 @@ class AttachmentBBCode extends AbstractBBCode { if ($attachment->showAsImage() && $attachment->canViewPreview() && $parser->getOutputType() == 'text/html') { // image $alignment = (isset($openingTag['attributes'][1]) ? $openingTag['attributes'][1] : ''); - $width = (isset($openingTag['attributes'][2]) ? $openingTag['attributes'][2] : 0); + $thumbnail = (isset($openingTag['attributes'][2]) ? $openingTag['attributes'][2] : false); - // check if width is valid and the original is accessible by viewer - if ($width > 0) { - if ($attachment->canDownload()) { - // check if width exceeds image width - if ($width > $attachment->width) { - $width = $attachment->width; - } + // backward compatibility, check if width is larger than thumbnail's width to display full version + if (is_int($thumbnail)) { + if ($thumbnail == 0) { + $thumbnail = true; } else { - $width = 0; + // true if supplied width is smaller or equal to thumbnail's width + $thumbnail = ($attachment->thumbnailWidth >= $thumbnail) ? true : false; } } + else if ($thumbnail !== false) { + $thumbnail = true; + } + + // check if width is valid and the original is accessible by viewer + if (!$thumbnail && !$attachment->canDownload()) { + $thumbnail = false; + } - if ($width > 0) { + if (!$thumbnail) { $class = ''; if ($alignment == 'left' || $alignment == 'right') { $class = 'messageFloatObject'.ucfirst($alignment); @@ -82,7 +88,7 @@ class AttachmentBBCode extends AbstractBBCode { $source = StringUtil::encodeHTML(LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment])); $title = StringUtil::encodeHTML($attachment->filename); - $result = ''; + $result = ''; } else { $linkParameters = [ diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php index 1d4da85b85..f18860e8f6 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php @@ -25,9 +25,23 @@ class HtmlInputNodeImg extends AbstractHtmlNode { continue; } + // TODO: add alignment detection + $alignment = 'none'; + $thumbnail = false; + + if (strpos($element->getAttribute('src'), 'thumbnail=1') !== false) { + $thumbnail = true; + } + + $attributes = [ + $attachmentID, + $alignment, + $thumbnail + ]; + $newElement = $element->ownerDocument->createElement('woltlab-metacode'); $newElement->setAttribute('data-name', 'attach'); - $newElement->setAttribute('data-attributes', base64_encode(JSON::encode([$attachmentID]))); + $newElement->setAttribute('data-attributes', base64_encode(JSON::encode($attributes))); DOMUtil::replaceElement($element, $newElement, false); } } diff --git a/wcfsetup/install/files/lib/system/message/embedded/object/AbstractMessageEmbeddedObjectHandler.class.php b/wcfsetup/install/files/lib/system/message/embedded/object/AbstractMessageEmbeddedObjectHandler.class.php index c390ccc761..c3b9461c1b 100644 --- a/wcfsetup/install/files/lib/system/message/embedded/object/AbstractMessageEmbeddedObjectHandler.class.php +++ b/wcfsetup/install/files/lib/system/message/embedded/object/AbstractMessageEmbeddedObjectHandler.class.php @@ -2,6 +2,7 @@ namespace wcf\system\message\embedded\object; use wcf\data\object\type\ObjectType; use wcf\data\DatabaseObjectDecorator; +use wcf\system\html\input\HtmlInputProcessor; use wcf\util\ArrayUtil; /** @@ -24,53 +25,11 @@ abstract class AbstractMessageEmbeddedObjectHandler extends DatabaseObjectDecora protected static $baseClass = ObjectType::class; /** - * Parses given message for specific bbcode parameters. - * - * @param string $message - * @param string $bbcode bbcode name - * @return array + * @inheritDoc */ - public static function getTextParameters($message, $bbcode) { - if (preg_match_all('~\['.$bbcode.'\](.*?)\[/'.$bbcode.'\]~i', $message, $matches)) { - $results = ArrayUtil::trim($matches[1]); - $results = array_unique($results); - - return $results; - } - + public function parse(HtmlInputProcessor $htmlInputProcessor, array $embeddedData) { + // TODO: DEBUG ONLY, remove this method! return []; } - /** - * Parses given message for specific bbcode parameters. - * - * @param string $message - * @param string $bbcode bbcode name - * @return array - */ - public static function getFirstParameters($message, $bbcode) { - $pattern = '~\['.$bbcode.'= - (\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'|(?:[^,\]]*)) - (?:,(?:\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^,\]]*))* - \]~ix'; - - if (preg_match_all($pattern, $message, $matches)) { - foreach ($matches[1] as &$value) { - // remove quotes - if (mb_substr($value, 0, 1) == "'" && mb_substr($value, -1) == "'") { - $value = str_replace("\'", "'", $value); - $value = str_replace("\\\\", "\\", $value); - - $value = mb_substr($value, 1, -1); - } - } - - $results = ArrayUtil::trim($matches[1]); - $results = array_unique($results); - - return $results; - } - - return []; - } } diff --git a/wcfsetup/install/files/lib/system/message/embedded/object/AttachmentMessageEmbeddedObjectHandler.class.php b/wcfsetup/install/files/lib/system/message/embedded/object/AttachmentMessageEmbeddedObjectHandler.class.php index 75f4e1e29d..2fb76c42ed 100644 --- a/wcfsetup/install/files/lib/system/message/embedded/object/AttachmentMessageEmbeddedObjectHandler.class.php +++ b/wcfsetup/install/files/lib/system/message/embedded/object/AttachmentMessageEmbeddedObjectHandler.class.php @@ -2,6 +2,7 @@ namespace wcf\system\message\embedded\object; use wcf\data\attachment\AttachmentList; use wcf\data\object\type\ObjectTypeCache; +use wcf\system\html\input\HtmlInputProcessor; use wcf\util\ArrayUtil; /** @@ -18,24 +19,30 @@ class AttachmentMessageEmbeddedObjectHandler extends AbstractMessageEmbeddedObje /** * @inheritDoc */ - public function parseMessage($message) { - $parsedAttachmentIDs = array_unique(ArrayUtil::toIntegerArray(array_merge(self::getFirstParameters($message, 'attach'), self::getTextParameters($message, 'attach')))); - if (!empty($parsedAttachmentIDs)) { - $attachmentIDs = []; - foreach ($parsedAttachmentIDs as $parsedAttachmentID) { - if ($parsedAttachmentID) $attachmentIDs[] = $parsedAttachmentID; - } + public function parse(HtmlInputProcessor $htmlInputProcessor, array $embeddedData) { + if (empty($embeddedData['attach'])) { + return []; + } + + $attachmentIDs = []; + for ($i = 0, $length = count($embeddedData['attach']); $i < $length; $i++) { + $attributes = $embeddedData['attach'][$i]; + $attachmentID = (!empty($attributes[0])) ? intval($attributes[0]) : 0; - if (!empty($attachmentIDs)) { - $attachmentList = new AttachmentList(); - $attachmentList->getConditionBuilder()->add("attachment.attachmentID IN (?)", [$attachmentIDs]); - $attachmentList->readObjectIDs(); - - return $attachmentList->getObjectIDs(); + if ($attachmentID > 0) { + $attachmentIDs[] = $attachmentID; } } - return false; + if (!empty($attachmentIDs)) { + $attachmentList = new AttachmentList(); + $attachmentList->getConditionBuilder()->add("attachment.attachmentID IN (?)", [$attachmentIDs]); + $attachmentList->readObjectIDs(); + + return $attachmentList->getObjectIDs(); + } + + return []; } /** diff --git a/wcfsetup/install/files/lib/system/message/embedded/object/IMessageEmbeddedObjectHandler.class.php b/wcfsetup/install/files/lib/system/message/embedded/object/IMessageEmbeddedObjectHandler.class.php index f41d5b27f5..541fa7a359 100644 --- a/wcfsetup/install/files/lib/system/message/embedded/object/IMessageEmbeddedObjectHandler.class.php +++ b/wcfsetup/install/files/lib/system/message/embedded/object/IMessageEmbeddedObjectHandler.class.php @@ -1,6 +1,7 @@ removeCodeTags($message); - + public function registerObjects(HtmlInputProcessor $htmlInputProcessor, $messageObjectType, $messageID) { // delete existing assignments $this->removeObjects($messageObjectType, [$messageID]); @@ -73,14 +71,20 @@ class MessageEmbeddedObjectManager extends SingletonFactory { // call embedded object handlers WCF::getDB()->beginTransaction(); + + $embeddedData = $htmlInputProcessor->getEmbeddedContent(); $returnValue = false; + + /** @var IMessageEmbeddedObjectHandler $handler */ foreach ($this->getEmbeddedObjectHandlers() as $handler) { - $objectIDs = $handler->parseMessage($message); + $objectIDs = $handler->parse($htmlInputProcessor, $embeddedData); + if (!empty($objectIDs)) { - $returnValue = true; foreach ($objectIDs as $objectID) { $statement->execute([$messageObjectTypeID, $messageID, $handler->objectTypeID, $objectID]); } + + $returnValue = true; } } WCF::getDB()->commitTransaction(); diff --git a/wcfsetup/install/files/style/ui/message.scss b/wcfsetup/install/files/style/ui/message.scss index d536e7c76b..acb67d42ba 100644 --- a/wcfsetup/install/files/style/ui/message.scss +++ b/wcfsetup/install/files/style/ui/message.scss @@ -370,6 +370,10 @@ > .messageText { @extend .htmlContent; + + img { + max-width: 100%; + } } } -- 2.20.1