From a1d9909379cf003113ed5b7c2b59b59ffa92729d Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Sun, 26 Dec 2021 17:31:53 +0000 Subject: [PATCH] [CORE][VisibilityScope] Use enum type instead of Bitmap --- components/Feed/Util/FeedController.php | 2 +- components/Posting/Posting.php | 14 +++++++------- plugins/ActivityPub/Util/Model/Note.php | 6 +++--- src/Core/VisibilityScope.php | 16 +++++++--------- src/Entity/Note.php | 12 ++++++------ 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/components/Feed/Util/FeedController.php b/components/Feed/Util/FeedController.php index ba1a678f64..3bda26e4bd 100644 --- a/components/Feed/Util/FeedController.php +++ b/components/Feed/Util/FeedController.php @@ -66,7 +66,7 @@ abstract class FeedController extends Controller foreach ($notes as $note) { switch ($note->getScope()) { case VisibilityScope::LOCAL: // The controller handles it if private - case VisibilityScope::PUBLIC: + case VisibilityScope::EVERYWHERE: $filtered_notes[] = $note; break; case VisibilityScope::ADDRESSEE: diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index 768496ab4d..eac313fed7 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -102,9 +102,9 @@ class Posting extends Component // TODO: if in group page, add GROUP visibility to the choices. $form_params[] = ['visibility', ChoiceType::class, ['label' => _m('Visibility:'), 'multiple' => false, 'expanded' => false, 'data' => 'public', 'choices' => [ - _m('Public') => VisibilityScope::PUBLIC, - _m('Local') => VisibilityScope::LOCAL, - _m('Addressee') => VisibilityScope::ADDRESSEE, + _m('Public') => VisibilityScope::EVERYWHERE->value, + _m('Local') => VisibilityScope::LOCAL->value, + _m('Addressee') => VisibilityScope::ADDRESSEE->value, ]]]; $form_params[] = ['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)], 'constraints' => [new Length(['max' => Common::config('site', 'text_limit')])]]]; $form_params[] = ['attachments', FileType::class, ['label' => _m('Attachments:'), 'multiple' => true, 'required' => false, 'invalid_message' => _m('Attachment not valid.')]]; @@ -135,7 +135,7 @@ class Posting extends Component throw new ClientException(_m('You must enter content or provide at least one attachment to post a note.')); } - if (!VisibilityScope::isValue($data['visibility'])) { + if (\is_null(VisibilityScope::tryFrom($data['visibility']))) { throw new ClientException(_m('You have selected an impossible visibility.')); } @@ -148,7 +148,7 @@ class Posting extends Component content: $data['content'], content_type: $content_type, language: $data['language'], - scope: $data['visibility'], + scope: VisibilityScope::from($data['visibility']), target: $data['in'] ?? null, attachments: $data['attachments'], process_note_content_extra_args: $extra_args, @@ -185,13 +185,13 @@ class Posting extends Component ?string $content, string $content_type, ?string $language = null, - ?int $scope = null, + ?VisibilityScope $scope = null, ?string $target = null, array $attachments = [], array $processed_attachments = [], array $process_note_content_extra_args = [], ): Note { - $scope ??= VisibilityScope::PUBLIC; // TODO: If site is private, default to LOCAL + $scope ??= VisibilityScope::EVERYWHERE; // TODO: If site is private, default to LOCAL $rendered = null; $mentions = []; if (!empty($content)) { diff --git a/plugins/ActivityPub/Util/Model/Note.php b/plugins/ActivityPub/Util/Model/Note.php index 0ab47a6e24..4c2043e8ea 100644 --- a/plugins/ActivityPub/Util/Model/Note.php +++ b/plugins/ActivityPub/Util/Model/Note.php @@ -170,11 +170,11 @@ class Note extends Model // Scope if (\in_array('https://www.w3.org/ns/activitystreams#Public', $type_note->get('to'))) { // Public: Visible for all, shown in public feeds - $map['scope'] = VisibilityScope::PUBLIC; + $map['scope'] = VisibilityScope::EVERYWHERE; } elseif (\in_array('https://www.w3.org/ns/activitystreams#Public', $type_note->get('cc'))) { // Unlisted: Visible for all but not shown in public feeds // It isn't the note that dictates what feed is shown in but the feed, it only dictates who can access it. - $map['scope'] = VisibilityScope::PUBLIC; + $map['scope'] = VisibilityScope::EVERYWHERE; } else { // Either Followers-only or Direct if ($type_note->get('directMessage') ?? false // Is DM explicitly? @@ -327,7 +327,7 @@ class Note extends Model // Target scope switch ($object->getScope()) { - case VisibilityScope::PUBLIC: + case VisibilityScope::EVERYWHERE: $attr['to'] = ['https://www.w3.org/ns/activitystreams#Public']; $attr['cc'] = [Router::url('actor_subscribers_id', ['id' => $object->getActor()->getId()], Router::ABSOLUTE_URL)]; break; diff --git a/src/Core/VisibilityScope.php b/src/Core/VisibilityScope.php index 780c810d3a..3c158d7243 100644 --- a/src/Core/VisibilityScope.php +++ b/src/Core/VisibilityScope.php @@ -21,14 +21,12 @@ declare(strict_types = 1); namespace App\Core; -use App\Util\Bitmap; - -class VisibilityScope extends Bitmap +enum VisibilityScope: int // having an int is just convenient { - public const PUBLIC = 1; // Can be shown everywhere (default) - public const LOCAL = 2; // Non-public and non-federated (default in private sites) - public const ADDRESSEE = 4; // Only if the actor is the author or one of the targets - public const GROUP = 8; // Only in the Group feed - public const COLLECTION = 16; // Only for the collection to see (same as addressee but not available in feeds, notifications only) - public const MESSAGE = 32; // Direct Message (same as Collection, but also with dedicated plugin) + case EVERYWHERE = 1; // Can be shown everywhere (default) + case LOCAL = 2; // Non-public and non-federated (default in private sites) + case ADDRESSEE = 4; // Only if the actor is the author or one of the targets + case GROUP = 8; // Only in the Group feed + case COLLECTION = 16; // Only for the collection to see (same as addressee but not available in feeds, notifications only) + case MESSAGE = 32; // Direct Message (same as Collection, but also with dedicated plugin) } diff --git a/src/Entity/Note.php b/src/Entity/Note.php index aa991e6cf9..438411e960 100644 --- a/src/Entity/Note.php +++ b/src/Entity/Note.php @@ -58,7 +58,7 @@ class Note extends Entity private ?int $reply_to = null; private bool $is_local; private ?string $source; - private int $scope = 1; + private int $scope = 1; //VisibilityScope::EVERYWHERE->value; private ?string $url; private ?int $language_id; private \DateTimeInterface $created; @@ -163,15 +163,15 @@ class Note extends Entity return $this->source; } - public function setScope(int $scope): self + public function setScope(VisibilityScope|int $scope): self { - $this->scope = $scope; + $this->scope = is_int($scope) ? $scope : $scope->value; return $this; } - public function getScope(): int + public function getScope(): VisibilityScope { - return $this->scope; + return VisibilityScope::from($this->scope); } public function setUrl(?string $url): self @@ -484,7 +484,7 @@ class Note extends Entity 'reply_to' => ['type' => 'int', 'not null' => false, 'default' => null, 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'description' => 'note replied to, null if root of a conversation'], 'is_local' => ['type' => 'bool', 'not null' => true, 'description' => 'was this note generated by a local actor'], 'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.code', 'multiplicity' => 'many to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'], - 'scope' => ['type' => 'int', 'not null' => true, 'default' => VisibilityScope::PUBLIC, 'description' => 'bit map for distribution scope; 1 = everywhere; 2 = this server only; 4 = addressees; 8 = groups; 16 = collection; 32 = messages'], + 'scope' => ['type' => 'int', 'not null' => true, 'default' => VisibilityScope::EVERYWHERE->value, 'description' => 'bit map for distribution scope; 1 = everywhere; 2 = this server only; 4 = addressees; 8 = groups; 16 = collection; 32 = messages'], 'url' => ['type' => 'text', 'description' => 'Permalink to Note'], 'language_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'one to many', 'description' => 'The language for this note'], 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],