Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions app/Actions/Search/AlbumSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,20 @@ public function queryTagAlbums(array $terms): Collection
}

/**
* @param string[] $terms
* @param string[] $terms
* @param Album|null $album the optional top album which is used as a search base
*
* @return Collection<int,Album>
*
* @throws InternalLycheeException
*/
public function queryAlbums(array $terms): Collection
public function queryAlbums(array $terms, ?Album $album = null): Collection
{
$album_query = Album::query()
->select(['albums.*'])
->join('base_albums', 'base_albums.id', '=', 'albums.id');
->join('base_albums', 'base_albums.id', '=', 'albums.id')
->when($album !== null, fn ($q) => $q->where('albums._lft', '>=', $album->_lft)
->where('albums._rgt', '<=', $album->_rgt));
$this->addSearchCondition($terms, $album_query);
$this->albumQueryPolicy->applyBrowsabilityFilter($album_query);

Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Gallery/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function search(GetSearchRequest $request, AlbumSearch $album_search, Pho
->orderBy(ColumnSortingPhotoType::TAKEN_AT->value, OrderSortingType::ASC->value)
->paginate(Configs::getValueAsInt('search_pagination_limit'));

$album_results = $album_search->queryAlbums($terms);
$album_results = $album_search->queryAlbums($terms, $album);

return ResultsResource::fromData($album_results, $photo_results);
}
Expand Down
13 changes: 11 additions & 2 deletions app/Http/Requests/Search/GetSearchRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use function Safe\base64_decode;
use function Safe\preg_match_all;

class GetSearchRequest extends BaseApiRequest implements HasAbstractAlbum, HasTerms
{
Expand Down Expand Up @@ -59,10 +60,18 @@ protected function processValidatedValues(array $values, array $files): void
$this->album = $this->album_factory->findNullalbleAbstractAlbumOrFail($album_id);

// Escape special characters for a LIKE query
$this->terms = explode(' ', str_replace(
$terms = str_replace(
['\\', '%', '_'],
['\\\\', '\\%', '\\_'],
base64_decode($values[RequestAttribute::TERM_ATTRIBUTE], true)
));
);

// Explode the string by spaces but keep encapsulated strings as single terms
// This regex matches quoted strings and unquoted words
// Note: This regex is not perfect and may not handle all edge cases, but it works for most common cases.
// It captures quoted strings as a single match and unquoted words separately.
// Example: "hello world" foo bar -> ["hello world", "foo", "bar"]
preg_match_all('/"[^"]*"|\S+/', $terms, $matches);
$this->terms = array_map(fn ($term) => trim($term, '"'), $matches[0]);
}
}
4 changes: 2 additions & 2 deletions resources/js/views/gallery-panels/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ function goBack() {
if (photoId.value !== undefined) {
photoId.value = undefined;
photo.value = undefined;
router.push({ name: "search-with-album", params: { albumId: albumId.value } });
router.push({ name: "search", params: { albumId: albumId.value } });
return;
}

Expand Down Expand Up @@ -410,7 +410,7 @@ onKeyStroke("Escape", () => {

onMounted(() => {
if (photoId.value !== undefined) {
router.push({ name: "search-with-album", params: { albumId: albumId.value } });
router.push({ name: "search", params: { albumId: albumId.value } });
}

if (albumId.value !== "" && albumId.value !== ALL) {
Expand Down