diff --git a/src/Content/Smilies.php b/src/Content/Smilies.php index d231797b81..2e1a6cf19c 100644 --- a/src/Content/Smilies.php +++ b/src/Content/Smilies.php @@ -285,4 +285,33 @@ class Smilies return str_replace($matches[0], $t, $matches[0]); } + + /** + * Checks if the body doesn't contain any alphanumeric characters + * + * @param string $body Possibly-HTML post body + * @return boolean + */ + public static function isEmojiPost(string $body): bool + { + // Strips all whitespace + $conv = preg_replace('#\s#u', '', html_entity_decode($body)); + if (empty($conv)) { + return false; + } + + if (!class_exists('IntlChar')) { + // Most Emojis are 4 byte Unicode characters, so this is a good workaround, when IntlChar does not exist on the system + return strlen($conv) / mb_strlen($conv) == 4; + } + + for ($i = 0; $i < mb_strlen($conv); $i++) { + $character = mb_substr($conv, $i, 1); + + if (\IntlChar::isalnum($character) || \IntlChar::ispunct($character) || \IntlChar::isgraph($character) && (strlen($character) <= 2)) { + return false; + } + } + return true; + } } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 36355f9964..88df9511d4 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1791,12 +1791,8 @@ class BBCode $text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism", '', $text); } - if (!$for_plaintext && DI::config()->get('system', 'big_emojis') && ($simple_html != self::DIASPORA)) { - $conv = html_entity_decode(str_replace([' ', "\n", "\r"], '', $text)); - // Emojis are always 4 byte Unicode characters - if (!empty($conv) && (strlen($conv) / mb_strlen($conv) == 4)) { - $text = '' . $text . ''; - } + if (!$for_plaintext && DI::config()->get('system', 'big_emojis') && ($simple_html != self::DIASPORA) && Smilies::isEmojiPost($text)) { + $text = '' . $text . ''; } // Handle mentions and hashtag links diff --git a/src/Protocol/Relay.php b/src/Protocol/Relay.php index c4432e59a3..bf48352019 100644 --- a/src/Protocol/Relay.php +++ b/src/Protocol/Relay.php @@ -21,6 +21,7 @@ namespace Friendica\Protocol; +use Friendica\Content\Smilies; use Friendica\Content\Text\BBCode; use Friendica\Core\Logger; use Friendica\Core\Protocol; @@ -172,6 +173,11 @@ class Relay */ public static function isWantedLanguage(string $body, int $uri_id = 0, int $author_id = 0) { + if (empty($body) || Smilies::isEmojiPost($body)) { + Logger::debug('Empty body or only emojis', ['body' => $body]); + return true; + } + $languages = []; foreach (Item::getLanguageArray($body, 10, $uri_id, $author_id) as $language => $reliability) { if ($reliability > 0) { diff --git a/tests/src/Content/SmiliesTest.php b/tests/src/Content/SmiliesTest.php index a886f1ac01..38eb743e85 100644 --- a/tests/src/Content/SmiliesTest.php +++ b/tests/src/Content/SmiliesTest.php @@ -72,4 +72,75 @@ class SmiliesTest extends FixtureTest $output = Smilies::replaceFromArray($text, $smilies); self::assertEquals($expected, $output); } + + public function dataIsEmojiPost(): array + { + return [ + 'emoji' => [ + 'expected' => true, + 'body' => '๐Ÿ‘€', + ], + 'emojis' => [ + 'expected' => true, + 'body' => '๐Ÿ‘€๐Ÿคท', + ], + 'emoji+whitespace' => [ + 'expected' => true, + 'body' => ' ๐Ÿ‘€ ', + ], + 'empty' => [ + 'expected' => false, + 'body' => '', + ], + 'whitespace' => [ + 'expected' => false, + 'body' => ' + ', + ], + 'emoji+ASCII' => [ + 'expected' => false, + 'body' => '๐Ÿคทa', + ], + 'HTML entity whitespace' => [ + 'expected' => false, + 'body' => ' ', + ], + 'HTML entity else' => [ + 'expected' => false, + 'body' => '°', + ], + 'emojis+HTML whitespace' => [ + 'expected' => true, + 'body' => '๐Ÿ‘€ ๐Ÿคท', + ], + 'emojis+HTML else' => [ + 'expected' => false, + 'body' => '๐Ÿ‘€<๐Ÿคท', + ], + 'zwj' => [ + 'expected' => true, + 'body' => '๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€', + ], + 'zwj+whitespace' => [ + 'expected' => true, + 'body' => ' ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€ ', + ], + 'zwj+HTML whitespace' => [ + 'expected' => true, + 'body' => ' ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€ ', + ], + ]; + } + + /** + * @dataProvider dataIsEmojiPost + * + * @param bool $expected + * @param string $body + * @return void + */ + public function testIsEmojiPost(bool $expected, string $body) + { + $this->assertEquals($expected, Smilies::isEmojiPost($body)); + } }