forked from GNUsocial/gnu-social
		
	[PLUGIN][TagBasedFiltering] Add to user settings page and split adding tags from note/actor from editing blocked
This commit is contained in:
		
							
								
								
									
										150
									
								
								plugins/TagBasedFiltering/Controller/AddBlocked.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								plugins/TagBasedFiltering/Controller/AddBlocked.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types = 1);
 | 
			
		||||
 | 
			
		||||
// {{{ License
 | 
			
		||||
 | 
			
		||||
// This file is part of GNU social - https://www.gnu.org/software/social
 | 
			
		||||
//
 | 
			
		||||
// GNU social is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
// the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// GNU social is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
 | 
			
		||||
namespace Plugin\TagBasedFiltering\Controller;
 | 
			
		||||
 | 
			
		||||
use App\Core\Cache;
 | 
			
		||||
use App\Core\Controller;
 | 
			
		||||
use App\Core\DB\DB;
 | 
			
		||||
use App\Core\Form;
 | 
			
		||||
use function App\Core\I18n\_m;
 | 
			
		||||
use App\Entity\Actor;
 | 
			
		||||
use App\Entity\ActorTag;
 | 
			
		||||
use App\Entity\ActorTagBlock;
 | 
			
		||||
use App\Entity\Language;
 | 
			
		||||
use App\Entity\Note;
 | 
			
		||||
use App\Entity\NoteTag;
 | 
			
		||||
use App\Entity\NoteTagBlock;
 | 
			
		||||
use App\Util\Common;
 | 
			
		||||
use App\Util\Exception\RedirectException;
 | 
			
		||||
use Component\Tag\Tag;
 | 
			
		||||
use Functional as F;
 | 
			
		||||
use Plugin\TagBasedFiltering\TagBasedFiltering as TagFilerPlugin;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
 | 
			
		||||
use Symfony\Component\Form\SubmitButton;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
class AddBlocked extends Controller
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Edit the blocked tags of $type_name for target with ID $id. Handles both actor and note tags
 | 
			
		||||
     */
 | 
			
		||||
    private function addBlocked(
 | 
			
		||||
        Request $request,
 | 
			
		||||
        string $type_name,
 | 
			
		||||
        callable $calculate_target,
 | 
			
		||||
        callable $calculate_blocks,
 | 
			
		||||
        callable $calculate_tags,
 | 
			
		||||
        ?string $label,
 | 
			
		||||
        string $block_class,
 | 
			
		||||
    ) {
 | 
			
		||||
        $user           = Common::ensureLoggedIn();
 | 
			
		||||
        $target         = $calculate_target();
 | 
			
		||||
        $tag_blocks     = $calculate_blocks($user);
 | 
			
		||||
        $blockable_tags = $calculate_tags($tag_blocks);
 | 
			
		||||
 | 
			
		||||
        $form_definition = [];
 | 
			
		||||
        foreach ($blockable_tags as $nt) {
 | 
			
		||||
            $canon             = $nt->getCanonical();
 | 
			
		||||
            $form_definition[] = ["{$canon}:tag", TextType::class, ['data' => '#' . $nt->getTag(), 'label' => ' ']];
 | 
			
		||||
            $form_definition[] = ["{$canon}:use-canon", CheckboxType::class, ['label' => _m('Use canonical'), 'help' => _m('Block all similar tags'), 'required' => false, 'data' => true]];
 | 
			
		||||
            $form_definition[] = ["{$canon}:add", SubmitType::class, ['label' => _m('Block')]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $form = null;
 | 
			
		||||
        if (!empty($form_definition)) {
 | 
			
		||||
            $form = Form::create($form_definition);
 | 
			
		||||
            $form->handleRequest($request);
 | 
			
		||||
            if ($form->isSubmitted() && $form->isValid()) {
 | 
			
		||||
                $data = $form->getData();
 | 
			
		||||
                foreach ($form_definition as [$id, $_, $opts]) {
 | 
			
		||||
                    [$canon, $type] = explode(':', $id);
 | 
			
		||||
                    if ($type === 'add') {
 | 
			
		||||
                        /** @var SubmitButton $button */
 | 
			
		||||
                        $button = $form->get($id);
 | 
			
		||||
                        if ($button->isClicked()) {
 | 
			
		||||
                            Cache::delete($block_class::cacheKey($user->getId()));
 | 
			
		||||
                            Cache::delete(TagFilerPlugin::cacheKeys($user->getId())[$type_name]);
 | 
			
		||||
                            $new_tag       = Tag::ensureValid($data[$canon . ':tag']);
 | 
			
		||||
                            $language      = $target instanceof Note ? Language::getByNote($target)->getLocale() : $user->getActor()->getTopLanguage()->getLocale();
 | 
			
		||||
                            $canonical_tag = Tag::canonicalTag($new_tag, $language);
 | 
			
		||||
                            DB::persist($block_class::create([
 | 
			
		||||
                                'blocker'       => $user->getId(),
 | 
			
		||||
                                'tag'           => $new_tag,
 | 
			
		||||
                                'canonical'     => $canonical_tag,
 | 
			
		||||
                                'use_canonical' => $data[$canon . ':use-canon'],
 | 
			
		||||
                            ]));
 | 
			
		||||
                            DB::flush();
 | 
			
		||||
                            throw new RedirectException;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            '_template' => 'tag_based_filtering/add_blocked.html.twig',
 | 
			
		||||
            'type'      => $type_name,
 | 
			
		||||
            $type_name  => $target,
 | 
			
		||||
            'tags_form' => $form?->createView(),
 | 
			
		||||
            'label'     => $label,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Edit the user's list of blocked note tags, with the option of adding the notes from the note $note_id, if given
 | 
			
		||||
     */
 | 
			
		||||
    public function addBlockedNoteTags(Request $request, int $note_id)
 | 
			
		||||
    {
 | 
			
		||||
        return self::addBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            type_name: 'note',
 | 
			
		||||
            calculate_target: fn ()      => Note::getById($note_id),
 | 
			
		||||
            calculate_blocks: fn ($user) => NoteTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            calculate_tags: fn ($blocks) => F\reject(
 | 
			
		||||
                NoteTag::getByNoteId($note_id),
 | 
			
		||||
                fn (NoteTag $nt) => NoteTagBlock::checkBlocksNoteTag($nt, $blocks),
 | 
			
		||||
            ),
 | 
			
		||||
            label: _m('Tags in the note above:'),
 | 
			
		||||
            block_class: NoteTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addBlockedActorTags(Request $request, int $actor_id)
 | 
			
		||||
    {
 | 
			
		||||
        return self::addBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            type_name: 'actor',
 | 
			
		||||
            calculate_target: fn ()      => Actor::getById($actor_id),
 | 
			
		||||
            calculate_blocks: fn ($user) => ActorTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            calculate_tags: fn ($blocks) => F\reject(
 | 
			
		||||
                ActorTag::getByActorId($actor_id),
 | 
			
		||||
                fn (ActorTag $nt) => ActorTagBlock::checkBlocksActorTag($nt, $blocks),
 | 
			
		||||
            ),
 | 
			
		||||
            label: _m('Tags of the account above:'),
 | 
			
		||||
            block_class: ActorTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										151
									
								
								plugins/TagBasedFiltering/Controller/EditBlocked.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								plugins/TagBasedFiltering/Controller/EditBlocked.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types = 1);
 | 
			
		||||
 | 
			
		||||
// {{{ License
 | 
			
		||||
 | 
			
		||||
// This file is part of GNU social - https://www.gnu.org/software/social
 | 
			
		||||
//
 | 
			
		||||
// GNU social is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
// the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// GNU social is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
 | 
			
		||||
namespace Plugin\TagBasedFiltering\Controller;
 | 
			
		||||
 | 
			
		||||
use App\Core\Cache;
 | 
			
		||||
use App\Core\Controller;
 | 
			
		||||
use App\Core\DB\DB;
 | 
			
		||||
use App\Core\Form;
 | 
			
		||||
use function App\Core\I18n\_m;
 | 
			
		||||
use App\Entity\ActorTagBlock;
 | 
			
		||||
use App\Entity\NoteTagBlock;
 | 
			
		||||
use App\Util\Common;
 | 
			
		||||
use App\Util\Exception\RedirectException;
 | 
			
		||||
use Component\Tag\Tag;
 | 
			
		||||
use Plugin\TagBasedFiltering\TagBasedFiltering as TagFilerPlugin;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
 | 
			
		||||
use Symfony\Component\Form\SubmitButton;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
class EditBlocked extends Controller
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Worker function that handles both the note and actor tag blocking editing
 | 
			
		||||
     */
 | 
			
		||||
    private static function editBlocked(
 | 
			
		||||
        Request $request,
 | 
			
		||||
        string $type_name,
 | 
			
		||||
        callable $calculate_blocks,
 | 
			
		||||
        string $label,
 | 
			
		||||
        string $block_class,
 | 
			
		||||
    ) {
 | 
			
		||||
        $user       = Common::ensureLoggedIn();
 | 
			
		||||
        $tag_blocks = $calculate_blocks($user);
 | 
			
		||||
 | 
			
		||||
        $form_definition = [];
 | 
			
		||||
        foreach ($tag_blocks as $ntb) {
 | 
			
		||||
            $canon             = $ntb->getCanonical();
 | 
			
		||||
            $form_definition[] = ["{$canon}:old-tag", TextType::class, ['data' => '#' . $ntb->getTag(), 'label' => ' ', 'disabled' => true]];
 | 
			
		||||
            $form_definition[] = ["{$canon}:toggle-canon", SubmitType::class, ['label' => $ntb->getUseCanonical() ? _m('Set non-canonical') : _m('Set canonical')]];
 | 
			
		||||
            $form_definition[] = ["{$canon}:remove", SubmitType::class, ['label' => _m('Unblock')]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $blocked_form = null;
 | 
			
		||||
        if (!empty($form_definition)) {
 | 
			
		||||
            $blocked_form = Form::create($form_definition);
 | 
			
		||||
            $blocked_form->handleRequest($request);
 | 
			
		||||
            if ($blocked_form->isSubmitted() && $blocked_form->isValid()) {
 | 
			
		||||
                $data = $blocked_form->getData();
 | 
			
		||||
                foreach ($form_definition as [$id, $_, $opts]) {
 | 
			
		||||
                    [$canon, $type] = explode(':', $id);
 | 
			
		||||
                    if (\in_array($type, ['remove', 'toggle-canon'])) {
 | 
			
		||||
                        /** @var SubmitButton $button */
 | 
			
		||||
                        $button = $blocked_form->get($id);
 | 
			
		||||
                        if ($button->isClicked()) {
 | 
			
		||||
                            Cache::delete($block_class::cacheKey($user->getId()));
 | 
			
		||||
                            Cache::delete(TagFilerPlugin::cacheKeys($user->getId())[$type_name]);
 | 
			
		||||
                            switch ($type) {
 | 
			
		||||
                            case 'toggle-canon':
 | 
			
		||||
                                $ntb = DB::getReference($block_class, ['blocker' => $user->getId(), 'canonical' => $canon]);
 | 
			
		||||
                                $ntb->setUseCanonical(!$ntb->getUseCanonical());
 | 
			
		||||
                                DB::flush();
 | 
			
		||||
                                throw new RedirectException;
 | 
			
		||||
                            case 'remove':
 | 
			
		||||
                                $old_tag = $data[$canon . ':old-tag'];
 | 
			
		||||
                                DB::removeBy($block_class, ['blocker' => $user->getId(), 'canonical' => $canon]);
 | 
			
		||||
                                throw new RedirectException;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $add_block_form = Form::create([
 | 
			
		||||
            ['tag', TextType::class, ['label' => ' ']],
 | 
			
		||||
            ['use-canon', CheckboxType::class, ['label' => _m('Use canonical'), 'help' => _m('Block all similar tags'), 'required' => false, 'data' => true]],
 | 
			
		||||
            ['add', SubmitType::class, ['label' => _m('Block')]],
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $add_block_form->handleRequest($request);
 | 
			
		||||
        if ($add_block_form->isSubmitted() && $add_block_form->isValid()) {
 | 
			
		||||
            $data = $add_block_form->getData();
 | 
			
		||||
            Cache::delete($block_class::cacheKey($user->getId()));
 | 
			
		||||
            Cache::delete(TagFilerPlugin::cacheKeys($user->getId())[$type_name]);
 | 
			
		||||
            $new_tag       = Tag::ensureValid($data['tag']);
 | 
			
		||||
            $language      = $user->getActor()->getTopLanguage()->getLocale();
 | 
			
		||||
            $canonical_tag = Tag::canonicalTag($new_tag, $language);
 | 
			
		||||
            DB::persist($block_class::create([
 | 
			
		||||
                'blocker'       => $user->getId(),
 | 
			
		||||
                'tag'           => $new_tag,
 | 
			
		||||
                'canonical'     => $canonical_tag,
 | 
			
		||||
                'use_canonical' => $data['use-canon'],
 | 
			
		||||
            ]));
 | 
			
		||||
            DB::flush();
 | 
			
		||||
            throw new RedirectException;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            '_template'    => 'tag_based_filtering/settings_edit_blocked.html.twig',
 | 
			
		||||
            'type'         => $type_name,
 | 
			
		||||
            'blocked_form' => $blocked_form?->createView(),
 | 
			
		||||
            'add_block'    => $add_block_form->createView(),
 | 
			
		||||
            'label'        => $label,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function editBlockedNoteTags(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        return self::editBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            type_name: 'note',
 | 
			
		||||
            calculate_blocks: fn ($user) => NoteTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            label: _m('Add blocked note tag:'),
 | 
			
		||||
            block_class: NoteTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function editBlockedActorTags(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        return self::editBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            type_name: 'actor',
 | 
			
		||||
            calculate_blocks: fn ($user) => ActorTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            label: _m('Add blocked people tag:'),
 | 
			
		||||
            block_class: ActorTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,196 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types = 1);
 | 
			
		||||
 | 
			
		||||
// {{{ License
 | 
			
		||||
 | 
			
		||||
// This file is part of GNU social - https://www.gnu.org/software/social
 | 
			
		||||
//
 | 
			
		||||
// GNU social is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
// the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// GNU social is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// }}}
 | 
			
		||||
 | 
			
		||||
namespace Plugin\TagBasedFiltering\Controller;
 | 
			
		||||
 | 
			
		||||
use App\Core\Cache;
 | 
			
		||||
use App\Core\Controller;
 | 
			
		||||
use App\Core\DB\DB;
 | 
			
		||||
use App\Core\Form;
 | 
			
		||||
use function App\Core\I18n\_m;
 | 
			
		||||
use App\Entity\Actor;
 | 
			
		||||
use App\Entity\ActorTag;
 | 
			
		||||
use App\Entity\ActorTagBlock;
 | 
			
		||||
use App\Entity\Language;
 | 
			
		||||
use App\Entity\Note;
 | 
			
		||||
use App\Entity\NoteTag;
 | 
			
		||||
use App\Entity\NoteTagBlock;
 | 
			
		||||
use App\Util\Common;
 | 
			
		||||
use App\Util\Exception\RedirectException;
 | 
			
		||||
use Component\Tag\Tag;
 | 
			
		||||
use Functional as F;
 | 
			
		||||
use Plugin\TagBasedFiltering\TagBasedFiltering as TagFilerPlugin;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
 | 
			
		||||
use Symfony\Component\Form\SubmitButton;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
class TagBasedFiltering extends Controller
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Edit the blocked tags of $type_name for target with ID $id. Handles both actor and note tags
 | 
			
		||||
     */
 | 
			
		||||
    private function editBlocked(
 | 
			
		||||
        Request $request,
 | 
			
		||||
        ?int $id,
 | 
			
		||||
        string $type_name,
 | 
			
		||||
        callable $calculate_target,
 | 
			
		||||
        callable $calculate_blocks,
 | 
			
		||||
        callable $calculate_tags,
 | 
			
		||||
        string $new_label,
 | 
			
		||||
        string $existing_label,
 | 
			
		||||
        string $block_class,
 | 
			
		||||
    ) {
 | 
			
		||||
        $user           = Common::ensureLoggedIn();
 | 
			
		||||
        $target         = $calculate_target();
 | 
			
		||||
        $tag_blocks     = $calculate_blocks($user);
 | 
			
		||||
        $blockable_tags = $calculate_tags($tag_blocks);
 | 
			
		||||
 | 
			
		||||
        $new_tags_form_definition = [];
 | 
			
		||||
        foreach ($blockable_tags as $nt) {
 | 
			
		||||
            $canon                      = $nt->getCanonical();
 | 
			
		||||
            $new_tags_form_definition[] = ["{$canon}:new-tag", TextType::class, ['data' => '#' . $nt->getTag(), 'label' => ' ']];
 | 
			
		||||
            $new_tags_form_definition[] = ["{$canon}:use-canon", CheckboxType::class, ['label' => _m('Use canonical'), 'help' => _m('Block all similar tags'), 'required' => false, 'data' => true]];
 | 
			
		||||
            $new_tags_form_definition[] = ["{$canon}:add", SubmitType::class, ['label' => _m('Block')]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $existing_tags_form_definition = [];
 | 
			
		||||
        foreach ($tag_blocks as $ntb) {
 | 
			
		||||
            $canon                           = $ntb->getCanonical();
 | 
			
		||||
            $existing_tags_form_definition[] = ["{$canon}:old-tag", TextType::class, ['data' => '#' . $ntb->getTag(), 'label' => ' ', 'disabled' => true]];
 | 
			
		||||
            $existing_tags_form_definition[] = ["{$canon}:toggle-canon", SubmitType::class, ['label' => $ntb->getUseCanonical() ? _m('Set non-canonical') : _m('Set canonical')]];
 | 
			
		||||
            $existing_tags_form_definition[] = ["{$canon}:remove", SubmitType::class, ['label' => _m('Unblock')]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $new_tags_form = null;
 | 
			
		||||
        if (!empty($new_tags_form_definition) && $user->getId() !== $target->getActorId()) {
 | 
			
		||||
            $new_tags_form = Form::create($new_tags_form_definition);
 | 
			
		||||
            $new_tags_form->handleRequest($request);
 | 
			
		||||
            if ($new_tags_form->isSubmitted() && $new_tags_form->isValid()) {
 | 
			
		||||
                $data = $new_tags_form->getData();
 | 
			
		||||
                foreach ($new_tags_form_definition as [$id, $_, $opts]) {
 | 
			
		||||
                    [$canon, $type] = explode(':', $id);
 | 
			
		||||
                    if ($type === 'add') {
 | 
			
		||||
                        /** @var SubmitButton $button */
 | 
			
		||||
                        $button = $new_tags_form->get($id);
 | 
			
		||||
                        if ($button->isClicked()) {
 | 
			
		||||
                            Cache::delete($block_class::cacheKey($user->getId()));
 | 
			
		||||
                            Cache::delete(TagFilerPlugin::cacheKeys($user->getId())[$type_name]);
 | 
			
		||||
                            $new_tag       = Tag::ensureValid($data[$canon . ':new-tag']);
 | 
			
		||||
                            $language      = $target instanceof Note ? Language::getByNote($target)->getLocale() : $user->getActor()->getTopLanguage()->getLocale();
 | 
			
		||||
                            $canonical_tag = Tag::canonicalTag($new_tag, $language);
 | 
			
		||||
                            DB::persist($block_class::create([
 | 
			
		||||
                                'blocker'       => $user->getId(),
 | 
			
		||||
                                'tag'           => $new_tag,
 | 
			
		||||
                                'canonical'     => $canonical_tag,
 | 
			
		||||
                                'use_canonical' => $data[$canon . ':use-canon'],
 | 
			
		||||
                            ]));
 | 
			
		||||
                            DB::flush();
 | 
			
		||||
                            throw new RedirectException;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $existing_tags_form = null;
 | 
			
		||||
        if (!empty($existing_tags_form_definition)) {
 | 
			
		||||
            $existing_tags_form = Form::create($existing_tags_form_definition);
 | 
			
		||||
            $existing_tags_form->handleRequest($request);
 | 
			
		||||
            if ($existing_tags_form->isSubmitted() && $existing_tags_form->isValid()) {
 | 
			
		||||
                $data = $existing_tags_form->getData();
 | 
			
		||||
                foreach ($existing_tags_form_definition as [$id, $_, $opts]) {
 | 
			
		||||
                    [$canon, $type] = explode(':', $id);
 | 
			
		||||
                    if (\in_array($type, ['remove', 'toggle-canon'])) {
 | 
			
		||||
                        /** @var SubmitButton $button */
 | 
			
		||||
                        $button = $existing_tags_form->get($id);
 | 
			
		||||
                        if ($button->isClicked()) {
 | 
			
		||||
                            Cache::delete($block_class::cacheKey($user->getId()));
 | 
			
		||||
                            Cache::delete(TagFilerPlugin::cacheKeys($user->getId())[$type_name]);
 | 
			
		||||
                            switch ($type) {
 | 
			
		||||
                            case 'toggle-canon':
 | 
			
		||||
                                $ntb = DB::getReference($block_class, ['blocker' => $user->getId(), 'canonical' => $canon]);
 | 
			
		||||
                                $ntb->setUseCanonical(!$ntb->getUseCanonical());
 | 
			
		||||
                                DB::flush();
 | 
			
		||||
                                throw new RedirectException;
 | 
			
		||||
                            case 'remove':
 | 
			
		||||
                                $old_tag = $data[$canon . ':old-tag'];
 | 
			
		||||
                                DB::removeBy($block_class, ['blocker' => $user->getId(), 'canonical' => $canon]);
 | 
			
		||||
                                throw new RedirectException;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            '_template'          => 'tag-based-filtering/edit-tags.html.twig',
 | 
			
		||||
            $type_name           => $target,
 | 
			
		||||
            'new_tags_form'      => $new_tags_form?->createView(),
 | 
			
		||||
            'existing_tags_form' => $existing_tags_form?->createView(),
 | 
			
		||||
            'new_label'          => $new_label,
 | 
			
		||||
            'existing_label'     => $existing_label,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Edit the user's list of blocked note tags, with the option of adding the notes from the note $note_id, if given
 | 
			
		||||
     */
 | 
			
		||||
    public function editBlockedNoteTags(Request $request, ?int $note_id)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->editBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            id: $note_id,
 | 
			
		||||
            type_name: 'note',
 | 
			
		||||
            calculate_target: fn ()          => !\is_null($note_id) ? Note::getById($note_id) : null,
 | 
			
		||||
            calculate_blocks: fn ($user)     => NoteTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            calculate_tags: fn ($tag_blocks) => F\reject(
 | 
			
		||||
                !\is_null($note_id) ? NoteTag::getByNoteId($note_id) : [],
 | 
			
		||||
                fn (NoteTag $nt) => NoteTagBlock::checkBlocksNoteTag($nt, $tag_blocks),
 | 
			
		||||
            ),
 | 
			
		||||
            new_label: _m('Tags in the note above:'),
 | 
			
		||||
            existing_label: _m('Tags you already blocked:'),
 | 
			
		||||
            block_class: NoteTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function editBlockedActorTags(Request $request, ?int $actor_id)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->editBlocked(
 | 
			
		||||
            request: $request,
 | 
			
		||||
            id: $actor_id,
 | 
			
		||||
            type_name: 'actor',
 | 
			
		||||
            calculate_target: fn ()          => !\is_null($actor_id) ? Actor::getById($actor_id) : null,
 | 
			
		||||
            calculate_blocks: fn ($user)     => ActorTagBlock::getByActorId($user->getId()),
 | 
			
		||||
            calculate_tags: fn ($tag_blocks) => F\reject(
 | 
			
		||||
                !\is_null($actor_id) ? ActorTag::getByActorId($actor_id) : [],
 | 
			
		||||
                fn (ActorTag $nt) => ActorTagBlock::checkBlocksActorTag($nt, $tag_blocks),
 | 
			
		||||
            ),
 | 
			
		||||
            new_label: _m('Tags of the account above:'),
 | 
			
		||||
            existing_label: _m('Tags you already blocked:'),
 | 
			
		||||
            block_class: ActorTagBlock::class,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -38,6 +38,7 @@ use App\Entity\Note;
 | 
			
		||||
use App\Entity\NoteTag;
 | 
			
		||||
use App\Entity\NoteTagBlock;
 | 
			
		||||
use Functional as F;
 | 
			
		||||
use Plugin\TagBasedFiltering\Controller as C;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
class TagBasedFiltering extends Plugin
 | 
			
		||||
@@ -55,8 +56,8 @@ class TagBasedFiltering extends Plugin
 | 
			
		||||
 | 
			
		||||
    public function onAddRoute(RouteLoader $r)
 | 
			
		||||
    {
 | 
			
		||||
        $r->connect(id: self::NOTE_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-note-tags/{note_id<\d+>?}', target: [Controller\TagBasedFiltering::class, 'editBlockedNoteTags']);
 | 
			
		||||
        $r->connect(id: self::ACTOR_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-actor-tags/{actor_id<\d+>?}', target: [Controller\TagBasedFiltering::class, 'editBlockedActorTags']);
 | 
			
		||||
        $r->connect(id: self::NOTE_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-note-tags/{note_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedNoteTags']);
 | 
			
		||||
        $r->connect(id: self::ACTOR_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-actor-tags/{actor_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedActorTags']);
 | 
			
		||||
        return Event::next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -105,4 +106,23 @@ class TagBasedFiltering extends Plugin
 | 
			
		||||
 | 
			
		||||
        return Event::next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool
 | 
			
		||||
    {
 | 
			
		||||
        if ($section === 'muting') {
 | 
			
		||||
            $tabs[] = [
 | 
			
		||||
                'title'      => 'Muted note tags',
 | 
			
		||||
                'desc'       => 'Edit your muted note tags',
 | 
			
		||||
                'id'         => 'settings-muting-note-tags',
 | 
			
		||||
                'controller' => C\EditBlocked::editBlockedNoteTags($request),
 | 
			
		||||
            ];
 | 
			
		||||
            $tabs[] = [
 | 
			
		||||
                'title'      => 'Muted people tags',
 | 
			
		||||
                'desc'       => 'Edit your muted people tags',
 | 
			
		||||
                'id'         => 'settings-muting-actor-tags',
 | 
			
		||||
                'controller' => C\EditBlocked::editBlockedActorTags($request),
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
        return Event::next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
{% extends 'base.html.twig' %}
 | 
			
		||||
{% import '/cards/note/view.html.twig' as noteView %}
 | 
			
		||||
 | 
			
		||||
{% block body %}
 | 
			
		||||
    {% if note is defined or actor is defined %}
 | 
			
		||||
        <div class="section-widget-padded">
 | 
			
		||||
            {% if note is defined %}
 | 
			
		||||
                {{ noteView.macro_note(note, {}) }}
 | 
			
		||||
            {% elseif actor is defined %}
 | 
			
		||||
                {% include 'cards/profile/view.html.twig' with {'actor': actor} only %}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if new_tags_form is not null %}
 | 
			
		||||
        <p>{{ new_label }}</p>
 | 
			
		||||
        {{ form(new_tags_form) }}
 | 
			
		||||
        <hr>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if existing_tags_form is not null %}
 | 
			
		||||
        <p>{{ existing_label }}</p>
 | 
			
		||||
        {{ form(existing_tags_form) }}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
{% extends 'base.html.twig' %}
 | 
			
		||||
{% import '/cards/note/view.html.twig' as noteView %}
 | 
			
		||||
 | 
			
		||||
{% block stylesheets %}
 | 
			
		||||
    {{ parent() }}
 | 
			
		||||
    <link rel="stylesheet" href="{{ asset('assets/default_theme/css/pages/feeds.css') }}" type="text/css">
 | 
			
		||||
{% endblock stylesheets %}
 | 
			
		||||
 | 
			
		||||
{% block body %}
 | 
			
		||||
    {% if note is defined or actor is defined %}
 | 
			
		||||
        <div class="section-widget-padded">
 | 
			
		||||
            {% if note is defined and note is not null %}
 | 
			
		||||
                {{ noteView.macro_note(note, {}) }}
 | 
			
		||||
            {% elseif actor is defined and actor is not null  %}
 | 
			
		||||
                {% include 'cards/profile/view.html.twig' with {'actor': actor} only %}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if tags_form is not null %}
 | 
			
		||||
        <p>{{ label }}</p>
 | 
			
		||||
        {{ form(tags_form) }}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    <div class="section-widget-button-like">
 | 
			
		||||
        <a href="{{ url('settings', {'open': 'settings-muting-' ~ type ~ '-tags-details'}) }}">{% trans %}Go to %type% muting settings{% endtrans %}</a>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
<div class='form'>
 | 
			
		||||
    {% if blocked_form is not null %}
 | 
			
		||||
        {{ form(blocked_form) }}
 | 
			
		||||
    {% else %}
 | 
			
		||||
        <em>{% trans %}No blocked %type% tags{% endtrans %}</em>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    <hr>
 | 
			
		||||
    <p>{{ label }}</p>
 | 
			
		||||
    {{ form(add_block) }} 
 | 
			
		||||
</div>
 | 
			
		||||
@@ -66,6 +66,11 @@
 | 
			
		||||
                {{ _self.settings_details_container('Profile', 'Personal Information, Avatar and Profile', 'settings-profile-details', profile_tabs, _context) }}
 | 
			
		||||
            </li>
 | 
			
		||||
            <hr>
 | 
			
		||||
            <li>
 | 
			
		||||
                {% set muting_tabs = handle_event('PopulateSettingsTabs', app.request, 'muting') %}
 | 
			
		||||
                {{ _self.settings_details_container('Muting', 'Blocked tags and actors', 'settings-muting-details', muting_tabs, _context) }}
 | 
			
		||||
            </li>
 | 
			
		||||
            <hr>
 | 
			
		||||
            <li>
 | 
			
		||||
                {{ _self.settings_details_element('Email', 'Set incoming and outgoing email settings', 'settings-email-details', email_form, _context) }}
 | 
			
		||||
            </li>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user