[COMPONENT][Posting][Tag] Add mechanism for adding extra fields to and handling the data from the Posting form. Add 'use canonical tag' field

This commit is contained in:
Hugo Sales 2021-12-04 12:58:27 +00:00
parent 314859b775
commit 2f5bde913c
No known key found for this signature in database
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 61 additions and 12 deletions

View File

@ -34,9 +34,6 @@ use App\Core\Router\Router;
use App\Core\Security;
use App\Entity\Activity;
use App\Entity\Actor;
use Component\Attachment\Entity\ActorToAttachment;
use Component\Attachment\Entity\Attachment;
use Component\Attachment\Entity\AttachmentToNote;
use App\Entity\Language;
use App\Entity\Note;
use App\Util\Common;
@ -46,6 +43,9 @@ use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException;
use App\Util\Form\FormFields;
use App\Util\Formatting;
use Component\Attachment\Entity\ActorToAttachment;
use Component\Attachment\Entity\Attachment;
use Component\Attachment\Entity\AttachmentToNote;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -113,6 +113,9 @@ class Posting extends Component
],
];
}
Event::handle('PostingAddFormEntries', [$request, $actor, &$form_params]);
$form_params[] = ['post_note', SubmitType::class, ['label' => _m('Post')]];
$form = Form::create($form_params);
@ -122,7 +125,16 @@ class Posting extends Component
if ($form->isValid()) {
$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['language'], $data['attachments']);
$extra_args = [];
Event::handle('PostingHandleForm', [$request, $actor, $data, &$extra_args, $form_params, $form]);
self::storeLocalNote(
$user->getActor(),
$data['content'],
$content_type,
$data['language'],
$data['attachments'],
process_note_content_extra_args: $extra_args,
);
throw new RedirectException();
}
} catch (FormSizeFileException $sizeFileException) {
@ -142,8 +154,9 @@ class Posting extends Component
* $actor_id, possibly as a reply to note $reply_to and with flag
* $is_local. Sanitizes $content and $attachments
*
* @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
* @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
* @param array $process_note_content_extra_args Extra arguments for the event ProcessNoteContent
*
* @throws \App\Util\Exception\DuplicateFoundException
* @throws ClientException
@ -151,8 +164,15 @@ class Posting extends Component
*
* @return \App\Core\Entity|mixed
*/
public static function storeLocalNote(Actor $actor, string $content, string $content_type, string $language, array $attachments = [], $processed_attachments = [])
{
public static function storeLocalNote(
Actor $actor,
string $content,
string $content_type,
string $language,
array $attachments = [],
array $processed_attachments = [],
array $process_note_content_extra_args = [],
) {
$rendered = null;
$mentions = [];
Event::handle('RenderNoteContent', [$content, $content_type, &$rendered, $actor, $language, &$mentions]);
@ -181,7 +201,7 @@ class Posting extends Component
// Need file and note ids for the next step
$note->setUrl(Router::url('note_view', ['id' => $note->getId()], Router::ABSOLUTE_URL));
Event::handle('ProcessNoteContent', [$note, $content, $content_type]);
Event::handle('ProcessNoteContent', [$note, $content, $content_type, $process_note_content_extra_args]);
if ($processed_attachments !== []) {
foreach ($processed_attachments as [$a, $fname]) {

View File

@ -26,8 +26,10 @@ namespace Component\Tag;
use App\Core\Cache;
use App\Core\DB\DB;
use App\Core\Event;
use function App\Core\I18n\_m;
use App\Core\Modules\Component;
use App\Core\Router\Router;
use App\Entity\Actor;
use App\Entity\Language;
use App\Entity\Note;
use App\Entity\NoteTag;
@ -36,6 +38,8 @@ use App\Util\HTML;
use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\HttpFoundation\Request;
/**
* Component responsible for extracting tags from posted notes, as well as normalizing them
@ -62,15 +66,20 @@ class Tag extends Component
/**
* Process note by extracting any tags present
*/
public function onProcessNoteContent(Note $note, string $content): bool
public function onProcessNoteContent(Note $note, string $content, string $content_type, array $extra_args): bool
{
$matched_tags = [];
$processed_tags = false;
preg_match_all(self::TAG_REGEX, $content, $matched_tags, \PREG_SET_ORDER);
foreach ($matched_tags as $match) {
$tag = str_replace('#', '', self::ensureLength($match[2]));
$tag = self::ensureValid($match[2]);
$canonical_tag = self::canonicalTag($tag, Language::getFromId($note->getLanguageId())->getLocale());
DB::persist(NoteTag::create(['tag' => $tag, 'canonical' => $canonical_tag, 'note_id' => $note->getId()]));
DB::persist(NoteTag::create([
'tag' => $tag,
'canonical' => $canonical_tag,
'note_id' => $note->getId(),
'use_canonical' => $extra_args['tag_use_canonical'],
]));
Cache::pushList("tag-{$canonical_tag}", $note);
$processed_tags = true;
}
@ -94,6 +103,11 @@ class Tag extends Component
return HTML::html(['a' => ['attrs' => ['href' => $url, 'title' => $tag, 'rel' => 'tag'], $tag]], options: ['indent' => false]);
}
public static function ensureValid(string $tag)
{
return self::ensureLength(str_replace('#', '', $tag));
}
public static function ensureLength(string $tag): string
{
return mb_substr($tag, 0, self::MAX_TAG_LENGTH);
@ -147,4 +161,19 @@ class Tag extends Component
$actor_qb->join('App\Entity\ActorTag', 'actor_tag', Expr\Join::WITH, 'actor_tag.tagger = actor.id');
return Event::next;
}
public function onPostingAddFormEntries(Request $request, Actor $actor, array &$form_params)
{
$form_params[] = ['tag_use_canonical', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Make note tags canonical')]];
return Event::next;
}
public function onPostingHandleForm(Request $request, Actor $actor, array $data, array &$extra_args)
{
if (!isset($data['tag_use_canonical'])) {
throw new ClientException;
}
$extra_args['tag_use_canonical'] = $data['tag_use_canonical'];
return Event::next;
}
}