forked from GNUsocial/gnu-social
		
	[PLUGIN][Repeat] Repeat now repeats attachments as it should.
[COMPONENTS][Posting] Now accepts attachments already processed. [ENTITY][Note] Added getAttachmentsWithTitle().
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types = 1); | ||||
| declare(strict_types=1); | ||||
|  | ||||
| // {{{ License | ||||
|  | ||||
| @@ -28,7 +28,6 @@ use App\Core\DB\DB; | ||||
| use App\Core\Event; | ||||
| use App\Core\Form; | ||||
| use App\Core\GSFile; | ||||
| use function App\Core\I18n\_m; | ||||
| use App\Core\Modules\Component; | ||||
| use App\Core\Security; | ||||
| use App\Entity\Actor; | ||||
| @@ -51,6 +50,8 @@ use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException; | ||||
| use Symfony\Component\HttpFoundation\File\UploadedFile; | ||||
| use Symfony\Component\HttpFoundation\Request; | ||||
| use Symfony\Component\Validator\Constraints\Length; | ||||
| use function App\Core\I18n\_m; | ||||
| use function count; | ||||
|  | ||||
| class Posting extends Component | ||||
| { | ||||
| @@ -68,15 +69,15 @@ class Posting extends Component | ||||
|             return Event::next; | ||||
|         } | ||||
|  | ||||
|         $actor    = $user->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()]; | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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 () { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user