aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Comments
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2022-03-24 15:13:09 +0100
committerJoas Schilling <coding@schilljs.com>2022-03-24 15:13:09 +0100
commit367be7c55fd48583e0fdcd058b813a2f6e3fe5e1 (patch)
treec45ee460ec76579595be91a85abfb50605b73807 /lib/private/Comments
parentfbf1334dc8c192ebdd335663cacfb810daf4d841 (diff)
downloadnextcloud-server-367be7c55fd48583e0fdcd058b813a2f6e3fe5e1.tar.gz
nextcloud-server-367be7c55fd48583e0fdcd058b813a2f6e3fe5e1.zip
Allow reactions also with other combined emojis
Honerful copying the EmojiService from UserStatus for now I think this should be put into a decent place and then reused, but I couldn't find somethin short term before beta1 Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib/private/Comments')
-rw-r--r--lib/private/Comments/EmojiHelper.php101
-rw-r--r--lib/private/Comments/Manager.php10
2 files changed, 109 insertions, 2 deletions
diff --git a/lib/private/Comments/EmojiHelper.php b/lib/private/Comments/EmojiHelper.php
new file mode 100644
index 00000000000..a75919edbc9
--- /dev/null
+++ b/lib/private/Comments/EmojiHelper.php
@@ -0,0 +1,101 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2020, Georg Ehrke
+ *
+ * @author Georg Ehrke <oc.list@georgehrke.com>
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Comments;
+
+use OCP\IDBConnection;
+
+/**
+ * Copied OCA\UserStatus\Service\EmojiService
+ * Needs to be unified later
+ */
+class EmojiHelper {
+
+ /** @var IDBConnection */
+ private $db;
+
+ /**
+ * EmojiService constructor.
+ *
+ * @param IDBConnection $db
+ */
+ public function __construct(IDBConnection $db) {
+ $this->db = $db;
+ }
+
+ /**
+ * @return bool
+ */
+ public function doesPlatformSupportEmoji(): bool {
+ return $this->db->supports4ByteText() &&
+ \class_exists(\IntlBreakIterator::class);
+ }
+
+ /**
+ * @param string $emoji
+ * @return bool
+ */
+ public function isValidEmoji(string $emoji): bool {
+ $intlBreakIterator = \IntlBreakIterator::createCharacterInstance();
+ $intlBreakIterator->setText($emoji);
+
+ $characterCount = 0;
+ while ($intlBreakIterator->next() !== \IntlBreakIterator::DONE) {
+ $characterCount++;
+ }
+
+ if ($characterCount !== 1) {
+ return false;
+ }
+
+ $codePointIterator = \IntlBreakIterator::createCodePointInstance();
+ $codePointIterator->setText($emoji);
+
+ foreach ($codePointIterator->getPartsIterator() as $codePoint) {
+ $codePointType = \IntlChar::charType($codePoint);
+
+ // If the current code-point is an emoji or a modifier (like a skin-tone)
+ // just continue and check the next character
+ if ($codePointType === \IntlChar::CHAR_CATEGORY_MODIFIER_SYMBOL ||
+ $codePointType === \IntlChar::CHAR_CATEGORY_MODIFIER_LETTER ||
+ $codePointType === \IntlChar::CHAR_CATEGORY_OTHER_SYMBOL ||
+ $codePointType === \IntlChar::CHAR_CATEGORY_GENERAL_OTHER_TYPES) {
+ continue;
+ }
+
+ // If it's neither a modifier nor an emoji, we only allow
+ // a zero-width-joiner or a variation selector 16
+ $codePointValue = \IntlChar::ord($codePoint);
+ if ($codePointValue === 8205 || $codePointValue === 65039) {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index 384187accf3..123e4f6988d 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -59,6 +59,9 @@ class Manager implements ICommentsManager {
/** @var ITimeFactory */
protected $timeFactory;
+ /** @var EmojiHelper */
+ protected $emojiHelper;
+
/** @var IInitialStateService */
protected $initialStateService;
@@ -78,11 +81,13 @@ class Manager implements ICommentsManager {
LoggerInterface $logger,
IConfig $config,
ITimeFactory $timeFactory,
+ EmojiHelper $emojiHelper,
IInitialStateService $initialStateService) {
$this->dbConn = $dbConn;
$this->logger = $logger;
$this->config = $config;
$this->timeFactory = $timeFactory;
+ $this->emojiHelper = $emojiHelper;
$this->initialStateService = $initialStateService;
}
@@ -148,8 +153,9 @@ class Manager implements ICommentsManager {
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
}
- if ($comment->getVerb() === 'reaction' && mb_strlen($comment->getMessage()) > 2) {
- throw new \UnexpectedValueException('Reactions cannot be longer than 2 chars (emoji with skin tone have two chars)');
+ if ($comment->getVerb() === 'reaction' && !$this->emojiHelper->isValidEmoji($comment->getMessage())) {
+ // 4 characters: laptop + person + gender + skin color => "🧑🏽‍💻" is a single emoji from the picker
+ throw new \UnexpectedValueException('Reactions can only be a single emoji');
}
if ($comment->getId() === '') {