Skip to content

Instantly share code, notes, and snippets.

@opejovic
Created December 17, 2019 17:52
Show Gist options
  • Save opejovic/880d6fa432619048e7ec0e170f9db6bd to your computer and use it in GitHub Desktop.
Save opejovic/880d6fa432619048e7ec0e170f9db6bd to your computer and use it in GitHub Desktop.
<?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