Code Review
I have created a topic on Code Review branch.
Question
I'm using haversine formula to count distance from selected post-code to desired destination.
App\Models\Business.php
public function scopeDistance($query, $latitude, $longitude, $radius)
{
$query->getQuery()->orders = [];
return $query->select('*')
->selectRaw("( 3959 * acos( cos( radians($latitude) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians($longitude) ) + sin( radians($latitude) ) * sin(radians(latitude)) ) ) AS distance")
->having('distance', '<=', $radius)
->orderBy('distance');
}
Everything seems pretty ok, except when i use paginate()
method instead of get()
I have been looking for solution, there are lots of topics describing this problem, but seems that people didn't come up with good solution for it.
Some solutions in my case caused incorrect values. Maybe i did something wrong - not sure...
However i came up with this solution and i would like to hear any feedback if it's ok in terms of performance and memory usage.
function custom_paginator($builder, $per_page)
{
$path = current_route();
$current_page = \Illuminate\Pagination\Paginator::resolveCurrentPage();
if ( ! isset($builder->getQuery()->columns[1])) $count = $builder->count();
else
{
$query = clone $builder->getQuery();
$query->columns = [ $query->columns[1] ];
$query->orders = null;
$count = array_get(\DB::select("select count(*) as count from ({$query->toSql()}) as haversine", $query->getBindings()), 0)->count;
}
return new \Illuminate\Pagination\LengthAwarePaginator(
$builder->forPage($current_page, $per_page)->get(),
$count, $per_page, null, compact('path')
);
}
I haven't got any more ideas how to improve it, at least it works and i dont need to call something like
count = count($results = $builder->get());
$items = $results->forPage($curPage, $perPage);
feedback really appreciated.