diff --git a/wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.3_step1.php b/wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.3_step1.php
index 3166c11493..dc17365b4d 100644
--- a/wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.3_step1.php
+++ b/wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.3_step1.php
@@ -57,4 +57,9 @@
->columns([
DefaultFalseBooleanDatabaseTableColumn::create('showOnUserCard'),
]),
+ PartialDatabaseTable::create('wcf1_smiley')
+ ->columns([
+ NotNullVarchar255DatabaseTableColumn::create('emoji')
+ ->defaultValue(''),
+ ]),
];
diff --git a/wcfsetup/install/files/acp/templates/smileyAdd.tpl b/wcfsetup/install/files/acp/templates/smileyAdd.tpl
index 8901488211..6c57cddd05 100644
--- a/wcfsetup/install/files/acp/templates/smileyAdd.tpl
+++ b/wcfsetup/install/files/acp/templates/smileyAdd.tpl
@@ -80,7 +80,7 @@
-
+
{if $errorField == 'aliases'}
{lang}wcf.acp.smiley.aliases.error.{$errorType}{/lang}
@@ -88,6 +88,20 @@
{/if}
+
+
+
+ -
+
+
+ {if $errorField == 'emoji'}
+
+ {lang}wcf.acp.smiley.emoji.error.{$errorType}{/lang}
+
+ {/if}
+ {lang}wcf.acp.smiley.emoji.description{/lang}
+
+
diff --git a/wcfsetup/install/files/lib/acp/form/SmileyAddForm.class.php b/wcfsetup/install/files/lib/acp/form/SmileyAddForm.class.php
index c0480ad5fc..9ab33b36fa 100644
--- a/wcfsetup/install/files/lib/acp/form/SmileyAddForm.class.php
+++ b/wcfsetup/install/files/lib/acp/form/SmileyAddForm.class.php
@@ -84,6 +84,11 @@ class SmileyAddForm extends AbstractForm
*/
public $aliases = '';
+ /**
+ * unicode emoji that replaces this smiley during message reprocessing
+ */
+ public string $emoji = '';
+
/**
* path to the smiley file
* @var string
@@ -140,6 +145,7 @@ public function assignVariables()
'categoryID' => $this->categoryID,
'smileyCode' => $this->smileyCode,
'aliases' => $this->aliases,
+ 'emoji' => $this->emoji,
'smileyPath' => $this->smileyPath,
'smileyPath2x' => $this->smileyPath2x,
'categoryNodeList' => $this->categoryNodeTree->getIterator(),
@@ -187,6 +193,9 @@ public function readFormParameters()
if (isset($_POST['aliases'])) {
$this->aliases = StringUtil::unifyNewlines(StringUtil::trim($_POST['aliases']));
}
+ if (isset($_POST['emoji'])) {
+ $this->emoji = StringUtil::trim($_POST['emoji']);
+ }
if (isset($_POST['smileyPath'])) {
$this->smileyPath = FileUtil::removeLeadingSlash(StringUtil::trim($_POST['smileyPath']));
}
@@ -217,6 +226,7 @@ public function save()
'smileyTitle' => $this->smileyTitle,
'smileyCode' => $this->smileyCode,
'aliases' => $this->aliases,
+ 'emoji' => $this->emoji,
'smileyPath' => $this->smileyPath,
'smileyPath2x' => $this->smileyPath2x,
'showOrder' => $this->showOrder,
@@ -246,6 +256,7 @@ public function save()
$this->showOrder = 0;
$this->smileyPath = $this->smileyPath2x = '';
$this->aliases = '';
+ $this->emoji = '';
$this->uploadedFilename = $this->uploadedFilename2x = '';
I18nHandler::getInstance()->reset();
diff --git a/wcfsetup/install/files/lib/acp/form/SmileyEditForm.class.php b/wcfsetup/install/files/lib/acp/form/SmileyEditForm.class.php
index 3bc3141e4f..468ff6169a 100644
--- a/wcfsetup/install/files/lib/acp/form/SmileyEditForm.class.php
+++ b/wcfsetup/install/files/lib/acp/form/SmileyEditForm.class.php
@@ -77,6 +77,7 @@ public function save()
'smileyTitle' => $this->smileyTitle,
'smileyCode' => $this->smileyCode,
'aliases' => $this->aliases,
+ 'emoji' => $this->emoji,
'smileyPath' => $this->smileyPath,
'smileyPath2x' => $this->smileyPath2x,
'showOrder' => $this->showOrder,
@@ -106,6 +107,7 @@ public function readData()
$this->smileyCode = $this->smiley->smileyCode;
$this->aliases = $this->smiley->aliases;
+ $this->emoji = $this->smiley->emoji;
$this->smileyPath = $this->smiley->smileyPath;
$this->smileyPath2x = $this->smiley->smileyPath2x;
$this->showOrder = $this->smiley->showOrder;
diff --git a/wcfsetup/install/files/lib/data/smiley/Smiley.class.php b/wcfsetup/install/files/lib/data/smiley/Smiley.class.php
index a3e4c2d41e..0aafbd20a4 100644
--- a/wcfsetup/install/files/lib/data/smiley/Smiley.class.php
+++ b/wcfsetup/install/files/lib/data/smiley/Smiley.class.php
@@ -23,6 +23,7 @@
* @property-read string $smileyCode code used for displaying the smiley
* @property-read string $aliases alternative codes used for displaying the smiley
* @property-read int $showOrder position of the smiley in relation to the other smileys in the same category
+ * @property-read string $emoji unicode emoji that replaces this smiley when content is reprocessed
*/
class Smiley extends DatabaseObject implements ITitledObject
{
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 0a8d0d57ae..6f36785664 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
@@ -255,6 +255,18 @@ protected function handleSmiley(\DOMElement $element)
$code = $element->getAttribute('alt');
$smiley = SmileyCache::getInstance()->getSmileyByCode($code);
+
+ // Migrate legacy smiley element to the mapped unicode emoji.
+ if ($smiley !== null && $smiley->emoji !== '') {
+ $element->parentNode->insertBefore(
+ $element->ownerDocument->createTextNode($smiley->emoji),
+ $element
+ );
+ $element->parentNode->removeChild($element);
+
+ return;
+ }
+
if ($smiley === null || $this->smiliesFound === 50) {
$element->parentNode->insertBefore($element->ownerDocument->createTextNode($code), $element);
$element->parentNode->removeChild($element);
diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php
index fb7c06027a..ad6e348d5c 100644
--- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php
+++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php
@@ -607,12 +607,19 @@ protected function parseSmiley(\DOMText $text, string $value)
foreach ($smileyPatterns as $smileyPattern) {
$value = \preg_replace_callback($smileyPattern, function ($matches) use ($text) {
$smileyCode = $matches[0];
+ $smiley = self::$smilies[$smileyCode];
+
+ // Replace smiley with mapped unicode emoji so legacy smiley codes
+ // get migrated to native emojis whenever a message is reprocessed.
+ if ($smiley->emoji !== '') {
+ return $smiley->emoji;
+ }
+
if ($this->smileyCount === 50) {
return $smileyCode;
}
$this->smileyCount++;
- $smiley = self::$smilies[$smileyCode];
$element = $text->ownerDocument->createElement('img');
$element->setAttribute('src', $smiley->getURL());
$element->setAttribute('class', 'smiley');
diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php
index 4a2db25931..0c45d881a1 100644
--- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php
+++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php
@@ -41,6 +41,13 @@ public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProc
$code = $element->getAttribute('alt');
$smiley = SmileyCache::getInstance()->getSmileyByCode($code);
+
+ // Render the mapped unicode emoji instead of the legacy smiley image.
+ if ($smiley !== null && $smiley->emoji !== '') {
+ $htmlNodeProcessor->replaceElementWithText($element, $smiley->emoji, false);
+ continue;
+ }
+
if ($smiley === null || $this->outputType === 'text/plain') {
// output as raw code instead
$htmlNodeProcessor->replaceElementWithText($element, ' ' . $code . ' ', false);
diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml
index 386d027441..9d3600f3b4 100644
--- a/wcfsetup/install/lang/de.xml
+++ b/wcfsetup/install/lang/de.xml
@@ -2855,6 +2855,8 @@ Abschnitte dürfen nicht leer sein und nur folgende Zeichen enthalten: [a-z
+
+
- getPath()}“ interpretiert.]]>
diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml
index 8f86c398f9..25050b2209 100644
--- a/wcfsetup/install/lang/en.xml
+++ b/wcfsetup/install/lang/en.xml
@@ -2784,6 +2784,8 @@ If you have already bought the licenses for the listed apps, th
+
+
- getPath()}”.]]>
diff --git a/wcfsetup/setup/db/install_com.woltlab.wcf.php b/wcfsetup/setup/db/install_com.woltlab.wcf.php
index f1ad25700a..6b40769b76 100644
--- a/wcfsetup/setup/db/install_com.woltlab.wcf.php
+++ b/wcfsetup/setup/db/install_com.woltlab.wcf.php
@@ -3293,6 +3293,8 @@
->notNull(),
NotNullInt10DatabaseTableColumn::create('showOrder')
->defaultValue(0),
+ NotNullVarchar255DatabaseTableColumn::create('emoji')
+ ->defaultValue(''),
])
->indices([
DatabaseTablePrimaryIndex::create()