Skip to content

Instantly share code, notes, and snippets.

@ollieread
Created August 4, 2018 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ollieread/ebfad05e173a2e9fd0e58fa6b1da75b1 to your computer and use it in GitHub Desktop.
Save ollieread/ebfad05e173a2e9fd0e58fa6b1da75b1 to your computer and use it in GitHub Desktop.
<?php
namespace Sprocketbox\Quartermaster\Http\Actions;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Sprocketbox\Quartermaster\Contracts\Resource;
class Browse extends Action
{
public function name(): string
{
return 'browse';
}
public function handle(Request $request, Resource $resource): JsonResponse
{
$handler = $resource->handler();
if (! method_exists($handler, 'browse')) {
throw new \RuntimeException('Resource handler does not support browse action');
}
$data = $handler->browse($request->query('limit'));
if ($data instanceof Paginator) {
return $this->handlePagination($resource, $data);
}
return $this->handleCollection($resource, $data);
}
private function handlePagination(Resource $resource, Paginator $paginator): JsonResponse
{
$format = '<%s>; rel="%s"';
$links = [];
if (! \in_array($paginator->currentPage(), [0, 1], true)) {
$links[] = sprintf($format, $paginator->url(1), 'first');
$links[] = sprintf($format, $paginator->previousPageUrl(), 'prev');
}
if ($paginator->hasMorePages()) {
$links[] = sprintf($format, $paginator->nextPageUrl(), 'next');
}
if ($paginator instanceof LengthAwarePaginator) {
$links[] = sprintf($format, $paginator->url($paginator->lastPage()), 'last');
}
$headers = ['Links' => $links];
return $this->quartermaster->buildResponse($resource, collect($paginator->items()), $headers, 200);
}
private function handleCollection(Resource $resource, $data): JsonResponse
{
$data = ! ($data instanceof Collection) ? collect($data) : $data;
return $this->quartermaster->buildResponse($resource, $data, [], 200);
}
}
<?php
namespace Sprocketbox\Quartermaster;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Sprocketbox\Quartermaster\Contracts\Resource;
class Quartermaster
{
/**
* @var \Illuminate\Support\Collection
*/
protected $resources;
public function __construct()
{
$this->resources = new Collection;
}
public function registerResource(Resource $resource)
{
if (! $this->resources->has($resource->name())) {
$this->resources->put($resource->name(), $resource);
return $this;
}
throw new \InvalidArgumentException(sprintf('Resource %s is already registered', $resource->name()));
}
/**
* @param string $name
*
* @return null|Resource
*/
public function getResource(string $name): ?Resource
{
return $this->resources->get($name, null);
}
public function buildResponse(Resource $resource, $data, array $headers = [], int $status = 200): JsonResponse
{
$handler = $resource->handler();
$modified = $handler->lastModified($data);
if ($data instanceof Collection) {
$data = $data->map(function ($data) use ($handler) {
return $handler->transform($data);
});
} else {
$data = $handler->transform($data);
}
$content = ['data' => $data];
$response = response()->json($content, $status, $headers);
return $response
->setEtag(md5($response->content()))
->setLastModified($modified);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment