mirror of
https://github.com/friendica/friendica
synced 2024-11-10 05:42:54 +00:00
Merge pull request #10604 from MrPetovan/task/10603-ap-string-mentions
ActivityPub: Add support for non-link mentions
This commit is contained in:
commit
12773f1f4e
3 changed files with 162 additions and 9 deletions
|
@ -52,18 +52,14 @@ use Friendica\Util\Strings;
|
|||
class Processor
|
||||
{
|
||||
/**
|
||||
* Converts mentions from Pleroma into the Friendica format
|
||||
* Extracts the tag character (#, @, !) from mention links
|
||||
*
|
||||
* @param string $body
|
||||
*
|
||||
* @return string converted body
|
||||
* @return string
|
||||
*/
|
||||
private static function convertMentions($body)
|
||||
protected static function normalizeMentionLinks(string $body): string
|
||||
{
|
||||
$URLSearchString = "^\[\]";
|
||||
$body = preg_replace("/\[url\=([$URLSearchString]*)\]([#@!])(.*?)\[\/url\]/ism", '$2[url=$1]$3[/url]', $body);
|
||||
|
||||
return $body;
|
||||
return preg_replace('%\[url=([^\[\]]*)]([#@!])(.*?)\[/url]%ism', '$2[url=$1]$3[/url]', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,7 +459,7 @@ class Processor
|
|||
$content = self::replaceEmojis($content, $activity['emojis']);
|
||||
}
|
||||
|
||||
$content = self::convertMentions($content);
|
||||
$content = self::addMentionLinks($content, $activity['tags']);
|
||||
|
||||
if (!empty($activity['source'])) {
|
||||
$item['body'] = $activity['source'];
|
||||
|
@ -1198,4 +1194,34 @@ class Processor
|
|||
|
||||
return implode('', $kept_mentions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds links to string mentions
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $tags
|
||||
* @return string
|
||||
*/
|
||||
protected static function addMentionLinks(string $body, array $tags): string
|
||||
{
|
||||
// This prevents links to be added again to Pleroma-style mention links
|
||||
$body = self::normalizeMentionLinks($body);
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if (empty($tag['name']) || empty($tag['type']) || empty($tag['href']) || !in_array($tag['type'], ['Mention', 'Hashtag'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = substr($tag['name'], 0, 1);
|
||||
$name = substr($tag['name'], 1);
|
||||
if (!in_array($hash, Tag::TAG_CHARACTER)) {
|
||||
$hash = '';
|
||||
$name = $tag['name'];
|
||||
}
|
||||
|
||||
$body = str_replace($tag['name'], $hash . '[url=' . $tag['href'] . ']' . $name . '[/url]', $body);
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
|
|
40
tests/src/Protocol/ActivityPub/ProcessorMock.php
Normal file
40
tests/src/Protocol/ActivityPub/ProcessorMock.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021, the Friendica project
|
||||
*
|
||||
* @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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Test\src\Protocol\ActivityPub;
|
||||
|
||||
use Friendica\Protocol\ActivityPub\Processor;
|
||||
|
||||
/**
|
||||
* Class ProcessorMock
|
||||
*
|
||||
* Exposes protected methods for test in the inherited class
|
||||
*
|
||||
* @method static string addMentionLinks(string $body, array $tags)
|
||||
* @method static string normalizeMentionLinks(string $body)
|
||||
*/
|
||||
class ProcessorMock extends Processor
|
||||
{
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
return self::$name(...$arguments);
|
||||
}
|
||||
}
|
87
tests/src/Protocol/ActivityPub/ProcessorTest.php
Normal file
87
tests/src/Protocol/ActivityPub/ProcessorTest.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\src\Protocol\ActivityPub;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProcessorTest extends TestCase
|
||||
{
|
||||
public function dataNormalizeMentionLinks(): array
|
||||
{
|
||||
return [
|
||||
'one-link-@' => [
|
||||
'expected' => '@[url=https://example.com]Example[/url]',
|
||||
'body' => '[url=https://example.com]@Example[/url]',
|
||||
],
|
||||
'one-link-#' => [
|
||||
'expected' => '#[url=https://example.com]Example[/url]',
|
||||
'body' => '[url=https://example.com]#Example[/url]',
|
||||
],
|
||||
'one-link-!' => [
|
||||
'expected' => '![url=https://example.com]Example[/url]',
|
||||
'body' => '[url=https://example.com]!Example[/url]',
|
||||
],
|
||||
'wrong-hash-char' => [
|
||||
'expected' => '[url=https://example.com]%Example[/url]',
|
||||
'body' => '[url=https://example.com]%Example[/url]',
|
||||
],
|
||||
'multiple-links' => [
|
||||
'expected' => '@[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url]',
|
||||
'body' => '[url=https://example.com]@Example[/url] [url=https://example.com]#Example[/url] [url=https://example.com]!Example[/url]',
|
||||
],
|
||||
'already-correct-format' => [
|
||||
'expected' => '@[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url]',
|
||||
'body' => '@[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url]',
|
||||
],
|
||||
'mixed-format' => [
|
||||
'expected' => '@[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url] @[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url]',
|
||||
'body' => '[url=https://example.com]@Example[/url] [url=https://example.com]#Example[/url] [url=https://example.com]!Example[/url] @[url=https://example.com]Example[/url] #[url=https://example.com]Example[/url] ![url=https://example.com]Example[/url]',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataNormalizeMentionLinks
|
||||
*
|
||||
* @param string $expected
|
||||
* @param string $body
|
||||
*/
|
||||
public function testNormalizeMentionLinks(string $expected, string $body)
|
||||
{
|
||||
$this->assertEquals($expected, ProcessorMock::normalizeMentionLinks($body));
|
||||
}
|
||||
|
||||
public function dataAddMentionLinks(): array
|
||||
{
|
||||
return [
|
||||
'issue-10603' => [
|
||||
'expected' => '@[url=https://social.wake.st/users/liaizon]liaizon@social.wake.st[/url] @[url=https://friendica.mrpetovan.com/profile/hypolite]hypolite@friendica.mrpetovan.com[/url] yes<br /><br />',
|
||||
'body' => '@liaizon@social.wake.st @hypolite@friendica.mrpetovan.com yes<br /><br />',
|
||||
'tags' => [
|
||||
[
|
||||
'type' => 'Mention',
|
||||
'href' => 'https://social.wake.st/users/liaizon',
|
||||
'name' => '@liaizon@social.wake.st'
|
||||
],
|
||||
[
|
||||
'type' => 'Mention',
|
||||
'href' => 'https://friendica.mrpetovan.com/profile/hypolite',
|
||||
'name' => '@hypolite@friendica.mrpetovan.com'
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataAddMentionLinks
|
||||
*
|
||||
* @param string $expected
|
||||
* @param string $body
|
||||
* @param array $tags
|
||||
*/
|
||||
public function testAddMentionLinks(string $expected, string $body, array $tags)
|
||||
{
|
||||
$this->assertEquals($expected, ProcessorMock::addMentionLinks($body, $tags));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue