From 01d5e84a0833467b09fbe5afcc3c7a960a7dc417 Mon Sep 17 00:00:00 2001 From: Phablulo Date: Wed, 29 Dec 2021 13:50:29 -0300 Subject: [PATCH] [COMPONENT][ACTOR CIRCLE] mention self tag circle with @#self_tag --- components/Tag/Tag.php | 8 +++-- src/Entity/ActorCircle.php | 5 +++ src/Routes/Main.php | 4 +++ src/Util/Formatting.php | 63 +++++++++++++++++++++++--------------- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/components/Tag/Tag.php b/components/Tag/Tag.php index 61ab27e276..51c5a87697 100644 --- a/components/Tag/Tag.php +++ b/components/Tag/Tag.php @@ -47,6 +47,7 @@ use Doctrine\ORM\QueryBuilder; use Functional as F; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\HttpFoundation\Request; +use App\Util\Nickname; /** * Component responsible for extracting tags from posted notes, as well as normalizing them @@ -57,9 +58,10 @@ use Symfony\Component\HttpFoundation\Request; */ class Tag extends Component { - public const MAX_TAG_LENGTH = 64; - public const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags - public const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}'; + public const MAX_TAG_LENGTH = 64; + public const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags + public const TAG_CIRCLE_REGEX = '/' . Nickname::BEFORE_MENTIONS . '@#([\pL\pN_\-\.]{1,64})/'; + public const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}'; public function onAddRoute($r): bool { diff --git a/src/Entity/ActorCircle.php b/src/Entity/ActorCircle.php index 4106812270..507db766d0 100644 --- a/src/Entity/ActorCircle.php +++ b/src/Entity/ActorCircle.php @@ -24,6 +24,7 @@ namespace App\Entity; use App\Core\Cache; use App\Core\DB\DB; use App\Core\Entity; +use App\Core\Router\Router; use DateTimeInterface; /** @@ -185,6 +186,10 @@ class ActorCircle extends Entity ); } + public function getUrl(int $type = Router::ABSOLUTE_PATH): string { + return Router::url('actor_circle', ['actor_id' => $this->getTagger(), 'tag' => $this->getTag()]); + } + public static function schemaDef(): array { return [ diff --git a/src/Routes/Main.php b/src/Routes/Main.php index b455918131..c534e9d7c5 100644 --- a/src/Routes/Main.php +++ b/src/Routes/Main.php @@ -60,6 +60,10 @@ abstract class Main $r->connect('panel', '/panel', [C\AdminPanel::class, 'site']); $r->connect('panel_site', '/panel/site', [C\AdminPanel::class, 'site']); + + // TODO: don't do + $r->connect('actor_circle', '/', RedirectController::class, ['defaults' => ['route' => 'feed_public']]); + // FAQ static pages foreach (['faq', 'contact', 'tags', 'groups', 'openid'] as $s) { $r->connect('doc_' . $s, '/doc/' . $s, C\TemplateController::class, ['template' => 'doc/faq/' . $s . '.html.twig']); diff --git a/src/Util/Formatting.php b/src/Util/Formatting.php index d626e5524a..72db7b979c 100644 --- a/src/Util/Formatting.php +++ b/src/Util/Formatting.php @@ -39,9 +39,12 @@ use App\Entity\Note; use App\Util\Exception\NicknameException; use App\Util\Exception\ServerException; use Component\Group\Entity\LocalGroup; +use Component\Tag\Tag; use Exception; use Functional as F; use InvalidArgumentException; +use App\Core\DB\DB; +use App\Entity\ActorCircle; abstract class Formatting { @@ -327,33 +330,43 @@ abstract class Formatting } } + @#/tag // TODO Tag subscriptions // @#tag => mention of all subscriptions tagged 'tag' - // $tag_matches = []; - // preg_match_all( - // '/' . Nickname::BEFORE_MENTIONS . '@#([\pL\pN_\-\.]{1,64})/', - // $text, - // $tag_matches, - // PREG_OFFSET_CAPTURE - // ); - // foreach ($tag_matches[1] as $tag_match) { - // $tag = self::canonicalTag($tag_match[0]); - // $plist = Profile_list::getByTaggerAndTag($actor->getID(), $tag); - // if (!$plist instanceof Profile_list || $plist->private) { - // continue; - // } - // $tagged = $actor->getTaggedSubscribers($tag); - // $url = common_local_url( - // 'showprofiletag', - // ['nickname' => $actor->getNickname(), 'tag' => $tag] - // ); - // $mentions[] = ['mentioned' => $tagged, - // 'type' => 'list', - // 'text' => $tag_match[0], - // 'position' => $tag_match[1], - // 'length' => mb_strlen($tag_match[0]), - // 'url' => $url, ]; - // } + $tag_matches = []; + preg_match_all( + Tag::TAG_CIRCLE_REGEX, + $text, + $tag_matches, + PREG_OFFSET_CAPTURE + ); + foreach ($tag_matches[1] as $tag_match) { + $tag = Tag::ensureValid($tag_match[0]); + $ac = DB::findOneBy(ActorCircle::class, [ + 'or' => [ + 'tagger' => $actor->getID(), + 'and' => [ + 'tagger' => null, + 'tagged' => $actor->getID(), + ] + ], + 'tag' => $tag, + ], return_null: true); + + if (\is_null($ac) || $ac->getPrivate()) { + continue; + } + $tagged = $ac->getSubscribedActors(); + $url = $ac->getUrl(); + $mentions[] = [ + 'mentioned' => $tagged, + 'type' => 'list', + 'text' => $tag_match[0], + 'position' => $tag_match[1], + 'length' => mb_strlen($tag_match[0]), + 'url' => $url, + ]; + } // Group mentions $group_matches = self::findMentionsRaw($text, '!');