Created
December 17, 2019 17:52
-
-
Save opejovic/880d6fa432619048e7ec0e170f9db6bd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Utilities; | |
use Carbon\Carbon; | |
use App\ApiRequest; | |
use Illuminate\Pagination\LengthAwarePaginator; | |
trait PreparesApiActivityData | |
{ | |
/** | |
* Prepare data for pagination. | |
* | |
* Merge the users requests with all of the days from the first ever created record until now, | |
* group it by the week, day, count by status. | |
* | |
* @param string $timestamp | |
* @param Collection $usersRequests | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function prepareData($timestamp, $usersRequests) | |
{ | |
return $this->getDaysFrom($timestamp) | |
->merge($this->format($usersRequests)) | |
->pipe([$this, 'sortAndGroupByWeek']) | |
->pipe([$this, 'groupByDayAndCount']); | |
} | |
/** | |
* Get the collection of days from the first ever created api request until now, | |
* and return it in proper format, so it can be merged with db data. | |
* | |
* @param string $timestamp | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function getDaysFrom($timestamp) | |
{ | |
$difference = Carbon::now()->endOfWeek() | |
->diffInDays(Carbon::parse($timestamp)->startOfWeek(), false); | |
return collect(range($difference, 0))->map(function ($i) { | |
return [ | |
'timestamp' => Carbon::now()->endOfWeek()->addDays($i)->format('Y-m-d h:m:s'), | |
'status' => null | |
]; | |
}); | |
} | |
/** | |
* Return the data in the proper format, so it can be merged with the total days. | |
* | |
* @param \Illuminate\Database\Eloquent\Collection $usersRequests | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function format($usersRequests) | |
{ | |
return $usersRequests->map(function ($item) { | |
return [ | |
'timestamp' => $item->timestamp, | |
'status' => $item->status | |
]; | |
}); | |
} | |
/** | |
* Sort the data by date, and group it by the week number. | |
* | |
* @param \Illuminate\Support\Collection $data | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function sortAndGroupByWeek($data) | |
{ | |
return $data->sortBy(function ($item) { | |
return $item['timestamp']; | |
})->groupBy(function ($item) { | |
return Carbon::parse($item['timestamp'])->format('W-Y'); | |
}); | |
} | |
/** | |
* Group the data by the day, then merge it with [ status => count ] | |
* so each day has Completed, Errored and Total status count. | |
* | |
* @param \Illuminate\Support\Collection $data | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function groupByDayAndCount($data) | |
{ | |
return $data->map(function ($items) { | |
# Group by the day inside the week | |
return $items->groupBy(function ($item) { | |
return Carbon::parse($item['timestamp'])->format('d-M-y'); | |
})->pipe([$this, 'countByStatus']); | |
}); | |
} | |
/** | |
* Map the data inside each day by status count. | |
* | |
* @param \Illuminate\Support\Collection $day | |
* @return \Illuminate\Support\Collection | |
*/ | |
public function countByStatus($day) | |
{ | |
return $day->map(function ($item) { | |
return [ | |
'total' => $item->filter(function ($i) { | |
return $i['status'] !== null; | |
})->count(), | |
'errored' => $item->filter(function ($i) { | |
return $i['status'] === ApiRequest::ERRORED; | |
})->count(), | |
]; | |
}); | |
} | |
/** | |
* Paginate the total api requests for the user. | |
* | |
* @param \Illuminate\Support\Collection $totalRequests | |
* @param \Illuminate\Http\Request $request | |
* @return \Illuminate\Pagination\LengthAwarePaginator | |
*/ | |
public function paginate($totalRequests, $request) | |
{ | |
$page = $request->page; | |
$perPage = 1; | |
$offset = ($page - 1) * $perPage; | |
$data = array_slice($totalRequests->all(), $offset, $perPage); | |
return new LengthAwarePaginator( | |
$data, | |
count($totalRequests), | |
$perPage, | |
$page, | |
['path' => route('api-activity')] | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment