From 0aa43783e81d6bcd3ade774b14f72ec7193f051a Mon Sep 17 00:00:00 2001 From: Eliseu Amaro Date: Wed, 17 Nov 2021 17:14:15 +0000 Subject: [PATCH] [PLUGIN][Repeat] Repeat now repeats attachments as it should. [COMPONENTS][Posting] Now accepts attachments already processed. [ENTITY][Note] Added getAttachmentsWithTitle(). --- components/Posting/Posting.php | 57 ++++++++++++++++------------ plugins/Repeat/Controller/Repeat.php | 28 ++++++-------- src/Entity/Note.php | 20 ++++++++++ 3 files changed, 64 insertions(+), 41 deletions(-) diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index 3bc890063c..f92e8901e5 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -1,6 +1,6 @@ getActor(); + $actor = $user->getActor(); $actor_id = $user->getId(); - $to_tags = []; - $tags = Cache::get( + $to_tags = []; + $tags = Cache::get( "actor-circle-{$actor_id}", - fn () => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id]), + fn() => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id]), ); foreach ($tags as $t) { - $t = $t['tag']; + $t = $t['tag']; $to_tags[$t] = $t; } @@ -93,31 +94,31 @@ class Posting extends Component Event::handle('PostingAvailableContentTypes', [&$available_content_types]); $context_actor = null; // This is where we'd plug in the group in which the actor is posting, or whom they're replying to - $form_params = [ - ['to', ChoiceType::class, ['label' => _m('To:'), 'multiple' => false, 'expanded' => false, 'choices' => $to_tags]], - ['visibility', ChoiceType::class, ['label' => _m('Visibility:'), 'multiple' => false, 'expanded' => false, 'data' => 'public', 'choices' => [_m('Public') => 'public', _m('Instance') => 'instance', _m('Private') => 'private']]], - ['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)], 'constraints' => [new Length(['max' => Common::config('site', 'text_limit')])]]], - ['attachments', FileType::class, ['label' => _m('Attachments:'), 'multiple' => true, 'required' => false, 'invalid_message' => _m('Attachment not valid.')]], + $form_params = [ + ['to', ChoiceType::class, ['label' => _m('To:'), 'multiple' => false, 'expanded' => false, 'choices' => $to_tags]], + ['visibility', ChoiceType::class, ['label' => _m('Visibility:'), 'multiple' => false, 'expanded' => false, 'data' => 'public', 'choices' => [_m('Public') => 'public', _m('Instance') => 'instance', _m('Private') => 'private']]], + ['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)], 'constraints' => [new Length(['max' => Common::config('site', 'text_limit')])]]], + ['attachments', FileType::class, ['label' => _m('Attachments:'), 'multiple' => true, 'required' => false, 'invalid_message' => _m('Attachment not valid.')]], FormFields::language($actor, $context_actor, label: 'Note language:', help: 'The language in which you wrote this note, so others can see it'), ]; - if (\count($available_content_types) > 1) { + if (count($available_content_types) > 1) { $form_params[] = ['content_type', ChoiceType::class, [ - 'label' => _m('Text format:'), 'multiple' => false, 'expanded' => false, - 'data' => $available_content_types[array_key_first($available_content_types)], + 'label' => _m('Text format:'), 'multiple' => false, 'expanded' => false, + 'data' => $available_content_types[array_key_first($available_content_types)], 'choices' => $available_content_types, ], ]; } $form_params[] = ['post_note', SubmitType::class, ['label' => _m('Post')]]; - $form = Form::create($form_params); + $form = Form::create($form_params); $form->handleRequest($request); if ($form->isSubmitted()) { try { if ($form->isValid()) { - $data = $form->getData(); + $data = $form->getData(); $content_type = $data['content_type'] ?? $available_content_types[array_key_first($available_content_types)]; self::storeLocalNote($user->getActor(), $data['content'], $content_type, $data['attachments']); throw new RedirectException(); @@ -139,29 +140,35 @@ class Posting extends Component * $actor_id, possibly as a reply to note $reply_to and with flag * $is_local. Sanitizes $content and $attachments * + * @param Actor $actor + * @param string $content + * @param string $content_type + * @param array $attachments Array of UploadedFile to be stored as GSFiles associated to this note + * @param array $processed_attachments Array of [Attachment, Attachment's name] to be associated to this $actor and Note + * @return \App\Core\Entity|mixed * @throws ClientException * @throws ServerException + * @throws \App\Util\Exception\DuplicateFoundException */ - public static function storeLocalNote(Actor $actor, string $content, string $content_type, array $attachments) + public static function storeLocalNote(Actor $actor, string $content, string $content_type, array $attachments = [], $processed_attachments = []) { $rendered = null; Event::handle('RenderNoteContent', [$content, $content_type, &$rendered, $actor]); $note = Note::create([ - 'actor_id' => $actor->getId(), - 'content' => $content, + 'actor_id' => $actor->getId(), + 'content' => $content, 'content_type' => $content_type, - 'rendered' => $rendered, - 'is_local' => true, + 'rendered' => $rendered, + 'is_local' => true, ]); - $processed_attachments = []; /** @var UploadedFile[] $attachments */ foreach ($attachments as $f) { - $filesize = $f->getSize(); + $filesize = $f->getSize(); $max_file_size = Common::getUploadLimit(); if ($max_file_size < $filesize) { throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' - . 'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize], )); + . 'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize],)); } Event::handle('EnforceUserFileQuota', [$filesize, $actor->getId()]); $processed_attachments[] = [GSFile::storeFileAsAttachment($f), $f->getClientOriginalName()]; diff --git a/plugins/Repeat/Controller/Repeat.php b/plugins/Repeat/Controller/Repeat.php index 84a5049201..cf16f7dcc6 100644 --- a/plugins/Repeat/Controller/Repeat.php +++ b/plugins/Repeat/Controller/Repeat.php @@ -26,6 +26,8 @@ namespace Plugin\Repeat\Controller; use App\Core\Controller; use App\Core\DB\DB; use App\Core\Form; +use App\Entity\Actor; +use Component\Posting\Posting; use function App\Core\I18n\_m; use App\Core\Log; use App\Core\Router\Router; @@ -53,7 +55,9 @@ class Repeat extends Controller public function repeatAddNote(Request $request, int $id): bool|array { $user = Common::ensureLoggedIn(); - $opts = ['actor_id' => $user->getId(), 'repeat_of' => $id]; + + $actor_id = $user->getId(); + $opts = ['actor_id' => $actor_id, 'repeat_of' => $id]; $note_already_repeated = DB::count('note_repeat', $opts) >= 1; // Before the form is rendered for the first time @@ -76,26 +80,18 @@ class Repeat extends Controller $form_add_to_repeat->handleRequest($request); if ($form_add_to_repeat->isSubmitted()) { // If the user goes back to the form, again - if (DB::count('note_repeat', ['actor_id' => $user->getId(), 'repeat_of' => $id]) >= 1) { + if (DB::count('note_repeat', ['actor_id' => $actor_id, 'repeat_of' => $id]) >= 1) { throw new ClientException(_m('Note already repeated!')); } if (!\is_null($note)) { - $actor_id = $user->getId(); - $content = $note->getContent(); - // Create a new note with the same content as the original - $repeat = Note::create([ - 'actor_id' => $actor_id, - 'content' => $content, - 'content_type' => $note->getContentType(), - 'rendered' => $note->getRendered(), - 'is_local' => true, - ]); - - // Update DB - DB::persist($repeat); - DB::flush(); + $repeat = Posting::storeLocalNote( + actor: Actor::getById($actor_id), + content:$note->getContent(), + content_type: $note->getContentType(), + processed_attachments: $note->getAttachmentsWithTitle() + ); // Find the id of the note we just created $repeat_id = $repeat->getId(); diff --git a/src/Entity/Note.php b/src/Entity/Note.php index 5539d77ddc..711e158085 100644 --- a/src/Entity/Note.php +++ b/src/Entity/Note.php @@ -241,6 +241,26 @@ class Note extends Entity }); } + public function getAttachmentsWithTitle(): array + { + return Cache::get('note-attachments-with-title-' . $this->id, function () { + $from_db = DB::dql( + <<<'EOF' + select att, atn.title + from attachment att + join attachment_to_note atn with atn.attachment_id = att.id + where atn.note_id = :note_id + EOF, + ['note_id' => $this->id], + ); + $results = []; + foreach ($from_db as $fd) { + $results[] = [$fd[0], $fd['title']]; + } + return $results; + }); + } + public function getLinks(): array { return Cache::get('note-links-' . $this->id, function () {