diff --git a/CHANGELOG.md b/CHANGELOG.md index aca3e79a1..b5df89b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Updates - Update ApiV1Controller, fix blocking remote accounts. Closes #4256 ([8e71e0c0](https://github.com/pixelfed/pixelfed/commit/8e71e0c0)) +- Update ComposeController, fix postgres location search. Closes #4242 and #4239 ([64a4a006](https://github.com/pixelfed/pixelfed/commit/64a4a006)) - ([](https://github.com/pixelfed/pixelfed/commit/)) ## [v0.11.5 (2023-03-25)](https://github.com/pixelfed/pixelfed/compare/v0.11.4...v0.11.5) diff --git a/app/Http/Controllers/ComposeController.php b/app/Http/Controllers/ComposeController.php index 8c2c91877..e817c6652 100644 --- a/app/Http/Controllers/ComposeController.php +++ b/app/Http/Controllers/ComposeController.php @@ -321,14 +321,30 @@ class ComposeController extends Controller ]); $pid = $request->user()->profile_id; abort_if(!$pid, 400); - $q = filter_var($request->input('q'), FILTER_SANITIZE_STRING); - $hash = hash('sha256', $q); - $key = 'pf:search:location:v1:id:' . $hash; - $popular = Cache::remember('pf:search:location:v1:popular', 86400, function() { - if(config('database.default') != 'mysql') { - return []; - } + $q = e($request->input('q')); + + $popular = Cache::remember('pf:search:location:v1:popular', 1209600, function() { $minId = SnowflakeService::byDate(now()->subDays(290)); + if(config('database.default') == 'pgsql') { + return Status::selectRaw('id, place_id, count(place_id) as pc') + ->whereNotNull('place_id') + ->where('id', '>', $minId) + ->orderByDesc('pc') + ->groupBy(['place_id', 'id']) + ->limit(400) + ->get() + ->filter(function($post) { + return $post; + }) + ->map(function($place) { + return [ + 'id' => $place->place_id, + 'count' => $place->pc + ]; + }) + ->unique('id') + ->values(); + } return Status::selectRaw('id, place_id, count(place_id) as pc') ->whereNotNull('place_id') ->where('id', '>', $minId) @@ -346,30 +362,30 @@ class ComposeController extends Controller ]; }); }); - $places = Cache::remember($key, 900, function() use($q, $popular) { - $q = '%' . $q . '%'; - return DB::table('places') - ->where('name', 'like', $q) - ->limit((strlen($q) > 5 ? 360 : 180)) - ->get() - ->sortByDesc(function($place, $key) use($popular) { - return $popular->filter(function($p) use($place) { - return $p['id'] == $place->id; - })->map(function($p) use($place) { - return in_array($place->country, ['Canada', 'USA', 'France', 'Germany', 'United Kingdom']) ? $p['count'] : 1; - })->values(); - }) - ->map(function($r) { - return [ - 'id' => $r->id, - 'name' => $r->name, - 'country' => $r->country, - 'url' => url('/discover/places/' . $r->id . '/' . $r->slug) - ]; - }) - ->values() - ->all(); - }); + $q = '%' . $q . '%'; + $wildcard = config('database.default') === 'pgsql' ? 'ilike' : 'like'; + + $places = DB::table('places') + ->where('name', $wildcard, $q) + ->limit((strlen($q) > 5 ? 360 : 30)) + ->get() + ->sortByDesc(function($place, $key) use($popular) { + return $popular->filter(function($p) use($place) { + return $p['id'] == $place->id; + })->map(function($p) use($place) { + return in_array($place->country, ['Canada', 'USA', 'France', 'Germany', 'United Kingdom']) ? $p['count'] : 1; + })->values(); + }) + ->map(function($r) { + return [ + 'id' => $r->id, + 'name' => $r->name, + 'country' => $r->country, + 'url' => url('/discover/places/' . $r->id . '/' . $r->slug) + ]; + }) + ->values() + ->all(); return $places; }