[COMPONENT][Search] Add support for searching for notes with media or with text

`note-types:media` will search for notes with an associated attachment or no text
This commit is contained in:
Hugo Sales 2021-12-11 20:57:48 +00:00
parent bad5efe819
commit 6b38972cca
Signed by untrusted user: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 45 additions and 2 deletions

View File

@ -26,9 +26,12 @@ use App\Core\Event;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router\RouteLoader; use App\Core\Router\RouteLoader;
use App\Entity\Note; use App\Entity\Note;
use App\Util\Formatting;
use Component\Attachment\Controller as C; use Component\Attachment\Controller as C;
use Component\Attachment\Entity as E; use Component\Attachment\Entity as E;
use Component\Attachment\Entity\AttachmentToNote; use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
class Attachment extends Component class Attachment extends Component
{ {
@ -56,9 +59,31 @@ class Attachment extends Component
{ {
Cache::delete("note-attachments-{$note->getId()}"); Cache::delete("note-attachments-{$note->getId()}");
E\AttachmentToNote::removeWhereNoteId($note->getId()); E\AttachmentToNote::removeWhereNoteId($note->getId());
foreach($note->getAttachments() as $attachment) { foreach ($note->getAttachments() as $attachment) {
$attachment->kill(); $attachment->kill();
} }
return Event::next; return Event::next;
} }
public function onSearchQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool
{
$note_qb->leftJoin(E\AttachmentToNote::class, 'attachment_to_note', Expr\Join::WITH, 'note.id = attachment_to_note.note_id');
return Event::next;
}
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
{
$include_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
if (Formatting::startsWith($term, ['note-types:', 'notes-incude:', 'note-filter:'])) {
if (\is_null($note_expr)) {
$note_expr = [];
}
if (array_intersect(explode(',', $include_term), ['media', 'image', 'images', 'attachment']) !== []) {
$note_expr[] = $eb->neq('attachment_to_note.note_id', null);
} else {
$note_expr[] = $eb->eq('attachment_to_note.note_id', null);
}
}
return Event::next;
}
} }

View File

@ -29,6 +29,8 @@ use function App\Core\I18n\_m;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Formatting;
use Doctrine\Common\Collections\ExpressionBuilder;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormView;
@ -131,4 +133,20 @@ class Search extends Component
$styles[] = 'components/Search/assets/css/view.css'; $styles[] = 'components/Search/assets/css/view.css';
return Event::next; return Event::next;
} }
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
{
$include_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
if (Formatting::startsWith($term, ['note-types:', 'notes-incude:', 'note-filter:'])) {
if (\is_null($note_expr)) {
$note_expr = [];
}
if (array_intersect(explode(',', $include_term), ['text', 'words']) !== []) {
$note_expr[] = $eb->neq('note.rendered', null);
} else {
$note_expr[] = $eb->eq('note.rendered', null);
}
}
return Event::next;
}
} }