-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathSearchController.php
More file actions
112 lines (95 loc) · 3.92 KB
/
SearchController.php
File metadata and controls
112 lines (95 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
declare(strict_types=1);
namespace App\Controller;
use App\ActivityPub\ActorHandle;
use App\DTO\SearchDto;
use App\Form\SearchType;
use App\Service\SearchManager;
use App\Service\SettingsManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class SearchController extends AbstractController
{
public function __construct(
private readonly SearchManager $manager,
private readonly SettingsManager $settingsManager,
private readonly LoggerInterface $logger,
) {
}
public function __invoke(Request $request): Response
{
$dto = new SearchDto();
$dto->since = new \DateTimeImmutable('@0');
$form = $this->createForm(SearchType::class, $dto, ['csrf_protection' => false]);
try {
$form = $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var SearchDto $dto */
$dto = $form->getData();
$query = trim($dto->q);
$this->logger->debug('searching for {query}', ['query' => $query]);
$objects = [];
// looking up handles (users and mags)
if (str_contains($query, '@') && $this->federatedSearchAllowed()) {
if ($handle = ActorHandle::parse($query)) {
$this->logger->debug('searching for a matched webfinger {query}', ['query' => $query]);
$objects = $this->manager->findActivityPubActorsByUsername($handle);
} else {
$this->logger->debug("query doesn't look like a valid handle...", ['query' => $query]);
}
}
// looking up object by AP id (i.e. urls)
if (false !== filter_var($query, FILTER_VALIDATE_URL) && $this->federatedSearchAllowed()) {
$this->logger->debug('Query is a valid url');
$objects = $this->findObjectsByApUrl($query);
}
$user = $this->getUser();
$res = $this->manager->findPaginated($user, $query, $this->getPageNb($request), authorId: $dto->user?->getId(), magazineId: $dto->magazine?->getId(), specificType: $dto->type, sinceDate: $dto->since);
$this->logger->debug('results: {num}', ['num' => $res->count()]);
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'html' => $this->renderView('search/_list.html.twig', [
'results' => $res,
]),
]);
}
return $this->render(
'search/front.html.twig',
[
'objects' => $objects,
'results' => $res,
'pagination' => $res,
'form' => $form->createView(),
'q' => $query,
]
);
}
} catch (\Exception $e) {
$this->logger->error($e);
}
return $this->render(
'search/front.html.twig',
[
'objects' => [],
'results' => [],
'form' => $form->createView(),
]
);
}
private function federatedSearchAllowed(): bool
{
return !$this->settingsManager->get('KBIN_FEDERATED_SEARCH_ONLY_LOGGEDIN')
|| $this->getUser();
}
private function findObjectsByApUrl(string $url): array
{
$result = $this->manager->findActivityPubObjectsByURL($url);
foreach ($result['errors'] as $error) {
/** @var \Exception $error */
$this->addFlash('error', $error->getMessage());
}
return $result['results'];
}
}