<validationpattern>^(left|right|none)$</validationpattern>
</attribute>
<attribute name="2">
- <validationpattern>^\d+$</validationpattern>
+ <!-- "\d+" is only matched for backward compatibility -->
+ <validationpattern>^(\d+|true|false)$</validationpattern>
</attribute>
</attributes>
</bbcode>
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);
$source = StringUtil::encodeHTML(LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment]));
$title = StringUtil::encodeHTML($attachment->filename);
- $result = '<a href="' . $source . '" title="' . $title . '" class="embeddedAttachmentLink jsImageViewer' . ($class ? ' '.$class : '') . '"><img src="' . $source . '" style="width: '.$width.'px" alt="" /></a>';
+ $result = '<a href="' . $source . '" title="' . $title . '" class="embeddedAttachmentLink jsImageViewer' . ($class ? ' '.$class : '') . '"><img src="' . $source . '" alt="" /></a>';
}
else {
$linkParameters = [
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);
}
}
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;
/**
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 [];
- }
}
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;
/**
/**
* @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 [];
}
/**
<?php
namespace wcf\system\message\embedded\object;
use wcf\data\DatabaseObject;
+use wcf\system\html\input\HtmlInputProcessor;
/**
* Default interface of embedded object handler.
*/
interface IMessageEmbeddedObjectHandler {
/**
- * Parses the given message to extract embedded objects.
- * Returns the IDs of found embedded objects.
+ * Processes embedded data and optionally accesses the current
+ * document to extract additional data. Returns the IDs of found
+ * embedded objects.
*
- * @param string $message
- * @return integer[]
+ * @param HtmlInputProcessor $htmlInputProcessor html input processor holding the current document
+ * @param mixed[] $embeddedData list of found embedded data with attributes
+ * @return integer[] ids of found embedded objects
*/
- public function parseMessage($message);
+ public function parse(HtmlInputProcessor $htmlInputProcessor, array $embeddedData);
/**
* Loads and returns embedded objects.
use wcf\data\object\type\ObjectTypeCache;
use wcf\system\bbcode\BBCodeParser;
use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\html\input\HtmlInputProcessor;
use wcf\system\SingletonFactory;
use wcf\system\WCF;
/**
* Registers the embedded objects found in given message.
*
- * @param string $messageObjectType
- * @param integer $messageID
- * @param string $message
- * @return boolean
+ * @param HtmlInputProcessor $htmlInputProcessor html input processor instance holding embedded object data
+ * @param string $messageObjectType message object type
+ * @param integer $messageID message id
+ * @return boolean true if at least one embedded object was found
*/
- public function registerObjects($messageObjectType, $messageID, $message) {
- // remove [code] tags
- $message = BBCodeParser::getInstance()->removeCodeTags($message);
-
+ public function registerObjects(HtmlInputProcessor $htmlInputProcessor, $messageObjectType, $messageID) {
// delete existing assignments
$this->removeObjects($messageObjectType, [$messageID]);
// 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();
> .messageText {
@extend .htmlContent;
+
+ img {
+ max-width: 100%;
+ }
}
}