[CONTROLLER][Feeds] Implement query for home feed: note-from:subscribed
This commit is contained in:
parent
e3efd25b43
commit
dabf5576d3
@ -25,6 +25,7 @@ use App\Core\Cache;
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Formatting;
|
||||
use Component\Attachment\Controller as C;
|
||||
@ -74,7 +75,7 @@ class Attachment extends Component
|
||||
/**
|
||||
* Populate $note_expr with the criteria for looking for notes with attachments
|
||||
*/
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr)
|
||||
{
|
||||
$include_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
|
||||
if (Formatting::startsWith($term, ['note-types:', 'notes-incude:', 'note-filter:'])) {
|
||||
|
@ -27,18 +27,21 @@ use App\Core\DB\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Subscription;
|
||||
use App\Util\Formatting;
|
||||
use Component\Search\Util\Parser;
|
||||
use Doctrine\Common\Collections\ExpressionBuilder;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class Feed extends Component
|
||||
{
|
||||
public static function query(string $query, int $page, ?string $language = null): array
|
||||
public static function query(string $query, int $page, ?string $language = null, ?Actor $actor = null): array
|
||||
{
|
||||
$note_criteria = null;
|
||||
$actor_criteria = null;
|
||||
if (!empty($query = trim($query))) {
|
||||
[$note_criteria, $actor_criteria] = Parser::parse($query, $language);
|
||||
[$note_criteria, $actor_criteria] = Parser::parse($query, $language, $actor);
|
||||
}
|
||||
$note_qb = DB::createQueryBuilder();
|
||||
$actor_qb = DB::createQueryBuilder();
|
||||
@ -62,11 +65,17 @@ class Feed extends Component
|
||||
return ['notes' => $notes ?? null, 'actors' => $actors ?? null];
|
||||
}
|
||||
|
||||
public function onSearchQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb)
|
||||
{
|
||||
$note_qb->leftJoin(Subscription::class, 'subscription', Expr\Join::WITH, 'note.actor_id = subscription.subscribed');
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert $term to $note_expr and $actor_expr, search criteria. Handles searching for text
|
||||
* notes, for different types of actors and for the content of text notes
|
||||
*/
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr)
|
||||
{
|
||||
if (str_contains($term, ':')) {
|
||||
$term = explode(':', $term);
|
||||
@ -90,6 +99,11 @@ class Feed extends Component
|
||||
case 'note-conversation':
|
||||
$note_expr = $eb->eq('note.conversation_id', (int) trim($term[1]));
|
||||
break;
|
||||
case 'note-from':
|
||||
if ($term[1] === 'subscribed') {
|
||||
$note_expr = $eb->eq('subscription.subscriber', $actor->getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
} elseif (Formatting::startsWith($term, 'actor-')) {
|
||||
switch ($term[0]) {
|
||||
|
@ -31,10 +31,10 @@ use App\Util\Formatting;
|
||||
use App\Util\Functional as GSF;
|
||||
use Component\Language\Controller as C;
|
||||
use Doctrine\Common\Collections\ExpressionBuilder;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Functional as F;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Language extends Component
|
||||
{
|
||||
@ -46,7 +46,9 @@ class Language extends Component
|
||||
|
||||
public function onFilterNoteList(?Actor $actor, array &$notes, Request $request)
|
||||
{
|
||||
if (\is_null($actor)) return Event::next;
|
||||
if (\is_null($actor)) {
|
||||
return Event::next;
|
||||
}
|
||||
$notes = F\select(
|
||||
$notes,
|
||||
fn (Note $n) => \in_array($n->getLanguageId(), ActorLanguage::getActorRelatedLanguagesIds($actor)),
|
||||
@ -58,7 +60,7 @@ class Language extends Component
|
||||
/**
|
||||
* Populate $note_expr or $actor_expr with an expression to match a language
|
||||
*/
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr)
|
||||
{
|
||||
$search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Search\Util;
|
||||
|
||||
use App\Core\Event;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Exception\ServerException;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
@ -52,7 +53,7 @@ abstract class Parser
|
||||
*
|
||||
* @return Criteria[]
|
||||
*/
|
||||
public static function parse(string $input, ?string $language = null, int $level = 0): array
|
||||
public static function parse(string $input, ?string $language = null, ?Actor $actor = null, int $level = 0): array
|
||||
{
|
||||
if ($level === 0) {
|
||||
$input = trim(preg_replace(['/\s+/', '/\s+AND\s+/', '/\s+OR\s+/'], [' ', '&', '|'], $input), ' |&');
|
||||
@ -77,7 +78,7 @@ abstract class Parser
|
||||
$term = mb_substr($input, $left, $end ? null : $right - $left);
|
||||
$note_res = null;
|
||||
$actor_res = null;
|
||||
Event::handle('SearchCreateExpression', [$eb, $term, $language, &$note_res, &$actor_res]);
|
||||
Event::handle('SearchCreateExpression', [$eb, $term, $language, $actor, &$note_res, &$actor_res]);
|
||||
if (\is_null($note_res) && \is_null($actor_res)) {
|
||||
throw new ServerException("No one claimed responsibility for a match term: {$term}");
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class Tag extends Component
|
||||
*
|
||||
* $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor
|
||||
*/
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, &$note_expr, &$actor_expr): bool
|
||||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr)
|
||||
{
|
||||
$search_term = str_contains($term, ':#') ? explode(':', $term)[1] : $term;
|
||||
$canon_search_term = self::canonicalTag($search_term, $language);
|
||||
|
@ -74,9 +74,10 @@ class Feeds extends FeedController
|
||||
public function home(Request $request): array
|
||||
{
|
||||
$data = Feed::query(
|
||||
query: 'from:subscribed-actors OR from:subscribed-groups',
|
||||
query: 'note-from:subscribed',
|
||||
page: $this->int('p'),
|
||||
language: Common::actor()?->getTopLanguage()?->getLocale(),
|
||||
actor: Common::actor(),
|
||||
);
|
||||
return [
|
||||
'_template' => 'feed/feed.html.twig',
|
||||
|
Loading…
Reference in New Issue
Block a user