1
0
mirror of https://github.com/Kovah/LinkAce.git synced 2025-01-18 05:38:40 +01:00

Allow users to search for links without lists or tags (#257)

This commit is contained in:
Kovah 2021-04-09 11:32:11 +02:00
parent ed3a846584
commit 7f76a86e66
No known key found for this signature in database
GPG Key ID: AAAA031BA9830D7B
5 changed files with 72 additions and 15 deletions

View File

@ -27,6 +27,8 @@ class SearchController extends Controller
'search_description' => true,
'private_only' => false,
'broken_only' => false,
'empty_tags' => false,
'empty_lists' => false,
'only_lists' => '',
'only_tags' => '',
'order_by' => $this->orderByOptions[0],
@ -55,6 +57,8 @@ class SearchController extends Controller
'broken_only' => $this->searchBrokenOnly,
'only_lists' => $this->searchLists,
'only_tags' => $this->searchTags,
'empty_tags' => $this->emptyTags,
'empty_lists' => $this->emptyLists,
'order_by' => $this->searchOrderBy,
]);
}

View File

@ -15,6 +15,8 @@ trait SearchesLinks
protected $searchBrokenOnly;
protected $searchLists;
protected $searchTags;
protected $emptyLists;
protected $emptyTags;
protected $searchOrderBy;
/** @var array */
@ -42,17 +44,19 @@ trait SearchesLinks
// Search for the URL
if ($this->searchQuery = $request->input('query', false)) {
$query = '%' . escapeSearchQuery($this->searchQuery) . '%';
$search->where('url', 'like', $query);
$search->where(function ($search) use ($request, $query) {
$search->where('url', 'like', $query);
// Also search for the title if applicable
if ($this->searchTitle = $request->input('search_title', false)) {
$search->orWhere('title', 'like', $query);
}
// Also search for the title if applicable
if ($this->searchTitle = $request->input('search_title', false)) {
$search->orWhere('title', 'like', $query);
}
// Also search for the title if applicable
if ($this->searchDescription = $request->input('search_description', false)) {
$search->orWhere('description', 'like', $query);
}
// Also search for the title if applicable
if ($this->searchDescription = $request->input('search_description', false)) {
$search->orWhere('description', 'like', $query);
}
});
}
// Show private only if applicable
@ -66,7 +70,9 @@ trait SearchesLinks
}
// Show by specific list only if applicable
if ($this->searchLists = $request->input('only_lists', false)) {
if ($this->emptyLists = $request->input('empty_lists', false)) {
$search->doesntHave('lists');
} elseif ($this->searchLists = $request->input('only_lists', false)) {
$search->whereHas('lists', function ($query) use ($request) {
$field = $request->isJson() ? 'id' : 'name';
$query->whereIn($field, explode(',', $this->searchLists));
@ -74,7 +80,9 @@ trait SearchesLinks
}
// Show by specific tag only if applicable
if ($this->searchTags = $request->input('only_tags', false)) {
if ($this->emptyTags = $request->input('empty_tags', false)) {
$search->doesntHave('tags');
} elseif ($this->searchTags = $request->input('only_tags', false)) {
$search->whereHas('tags', function ($query) use ($request) {
$field = $request->isJson() ? 'id' : 'name';
$query->whereIn($field, explode(',', $this->searchTags));

View File

@ -10,6 +10,8 @@ return [
'search_description' => 'Search Description',
'private_only' => 'Private Links only',
'broken_links' => 'Broken Links only',
'empty_tags' => 'without Tags',
'empty_lists' => 'without Lists',
'order_by' => 'Order by',
'order_by.title:asc' => 'Title ascending',

View File

@ -49,6 +49,29 @@
</div>
</div>
<div class="col-md d-flex align-items-center">
<div class="custom-control custom-checkbox">
<input type="checkbox" id="empty_tags" name="empty_tags" class="custom-control-input"
@if($query_settings['empty_tags']) checked @endif>
<label class="custom-control-label" for="empty_tags">
@lang('search.empty_tags')
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-md d-flex align-items-center">
<div class="custom-control custom-checkbox">
<input type="checkbox" id="broken_only" name="broken_only" class="custom-control-input"
@if($query_settings['broken_only']) checked @endif>
<label class="custom-control-label" for="broken_only">
@lang('search.broken_links')
</label>
</div>
</div>
<div class="col-md d-flex align-items-center">
<div class="custom-control custom-checkbox">
<input type="checkbox" id="private_only" name="private_only" class="custom-control-input"
@ -61,10 +84,10 @@
<div class="col-md d-flex align-items-center">
<div class="custom-control custom-checkbox">
<input type="checkbox" id="broken_only" name="broken_only" class="custom-control-input"
@if($query_settings['broken_only']) checked @endif>
<label class="custom-control-label" for="broken_only">
@lang('search.broken_links')
<input type="checkbox" id="empty_lists" name="empty_lists" class="custom-control-input"
@if($query_settings['empty_lists']) checked @endif>
<label class="custom-control-label" for="empty_lists">
@lang('search.empty_lists')
</label>
</div>
</div>

View File

@ -126,6 +126,18 @@ class SearchControllerTest extends TestCase
->assertDontSee('https://example.com');
}
public function testEmptyListSearchResult(): void
{
$response = $this->post('search', [
'query' => 'Test',
'empty_lists' => 'on',
]);
$response->assertOk()
->assertSee('https://empty-test.com')
->assertDontSee('https://test.com');
}
protected function setupTestData(): void
{
$tagExample = Tag::create([
@ -166,5 +178,13 @@ class SearchControllerTest extends TestCase
'is_private' => false,
'status' => Link::STATUS_BROKEN,
]);
Link::create([
'user_id' => $this->user->id,
'url' => 'https://empty-test.com',
'title' => 'Empty Test Site',
'description' => null,
'is_private' => false,
]);
}
}