Skip to content

Commit

Permalink
Add pagination attributes access (#29)
Browse files Browse the repository at this point in the history
* Add the ability to accept after and before

As they are encode already there is no need to parse them again

* Add 'getWithPagination' method to provide attribute data

* Update the readme to explain the pagination system

* Add an import statement where possible

* Fix typos

thanks @timothydc
  • Loading branch information
TVke authored Feb 28, 2023
1 parent 763e32f commit fd8badf
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,21 @@ If you would like to alter the redirect you may extend this controller.
You can now access the API. All resources return a [Laravel collection][laravel-docs-collections]... which means lots of fun!

```php

use TimothyDC\LightspeedRetailApi\Facades\LightspeedRetailApi;

// get all
$account = LightspeedRetailApi::api()->account()->get();

// filter with GET (with a limit and custom sorting
// filter with GET with a limit and custom sorting (full details: https://developers.lightspeedhq.com/retail/introduction/parameters/)
$categories = LightspeedRetailApi::api()->category()->get(null, ['limit' => 10, 'sort' => 'name']);

// get category with ID 20
$categories = LightspeedRetailApi::api()->category()->get(20);

// same as above, but better
$categories = LightspeedRetailApi::api()->category()->first(20);

```

Note that not all [resources][ls-added-resources] are added (yet). Feel free to add them yourself via a pull request!
Expand All @@ -132,8 +134,47 @@ $categories = LightspeedRetailApi::api()->category()->get(null, ['categoryID' =>
// get categories with their parent relation
$categories = LightspeedRetailApi::api()->category()->get(null, ['load_relations' => ['Parent']]);

// get sales sorted by timestamp in descending order
$sales = LightspeedRetailApi::api()->sale()->get(null, ['sort' => '-timestamp']);

```

#### Pagination
As of V3 of the Lightspeed Retail API the pagination works cursor based.
The full details of on how pagination works, you can find in the [Pagination API documentation](https://developers.lightspeedhq.com/retail/introduction/pagination/)

```php

use \TimothyDC\LightspeedRetailApi\Services\Lightspeed\ResourceSale;

$response = LightspeedRetailApi::api()->sale()->getWithPagination();

$attributes = $response['@attributes'];

// collect([
// 'next' => (request url),
// 'previous' => (request url),
// 'after' => (token),
// 'before' => (token),
// ])

$sales = $response[ResourceSale::$resource];

// Sales data as a collection

```

To get the next page of the resource, add the 'after' token to your request.

```php

$response = LightspeedRetailApi::api()->sale()->getWithPagination(null, ['after' => $attributes->after]);

```

The 'after' attribute will be empty on the last page and the 'before' attribute will be empty on the first page.
This is the same as the 'next' and 'previous' attributes as described in the [Pagination API documentation](https://developers.lightspeedhq.com/retail/introduction/pagination/)

---

### Automatic model synchronisation [optional]
Expand Down
3 changes: 2 additions & 1 deletion src/Http/Controllers/SaveAccessTokenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use TimothyDC\LightspeedRetailApi\Facades\LightspeedRetailApi;

class SaveAccessTokenController extends Controller
{
public function __invoke(Request $request): \Illuminate\Http\RedirectResponse
public function __invoke(Request $request): RedirectResponse
{
// save access token
LightspeedRetailApi::api()->startUpClient($request->get('code'));
Expand Down
5 changes: 5 additions & 0 deletions src/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public function get(int $id = null, array $query = []): Collection
return $this->client->get(static::$resource, $id, $query);
}

public function getWithPagination(int $id = null, array $query = []): Collection
{
return $this->client->getWithPagination(static::$resource, $id, $query);
}

/**
* @throws \TimothyDC\LightspeedRetailApi\Exceptions\LightspeedRetailException
*/
Expand Down
44 changes: 44 additions & 0 deletions src/Services/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,50 @@ public function get(string $resource = null, int $id = null, array $query = []):
return collect($response[$resource] ?? []);
}

public function getWithPagination(string $resource = null, int $id = null, array $query = []): Collection
{
$responseObject = Http::withHeaders(['Accept' => 'application/json'])
->withOptions(['handler' => $this->createHandlerStack()])
->get($this->getUrl($resource, $id) . $this->buildQueryString($query));

$this->logAction('GET ' . $this->getUrl($resource, $id), ['params' => func_get_args(), 'status' => $responseObject->status()]);

$response = $responseObject->json();

// unstructured way of requesting the "Account" resource
if (! $resource) {
return collect($response['Account']);
}

// fix Lightspeed unstructured way of returning an array when a multi dimensional array is expected
if (isset($response['@attributes']['count']) && $response['@attributes']['count'] === 1) {
$response[$resource] = [$response[$resource]];
}

$attributes = $response['@attributes'];
$after = '';
$before = '';

if ($attributes['next'] !== '') {
$matches = [];
preg_match('/after=([^&]+)/', $attributes['next'], $matches);
$after = array_key_exists(1, $matches) ? $matches[1] : '';
}

if ($attributes['previous'] !== '') {
$matches = [];
preg_match('/before=([^&]+)/', $attributes['previous'], $matches);
$before = array_key_exists(1, $matches) ? $matches[1] : '';
}

$attributes['after'] = $after;
$attributes['before'] = $before;
$response['@attributes'] = collect($attributes);
$response[$resource] = collect($response[$resource] ?? []);

return collect($response);
}

/**
* @throws DuplicateResourceException
* @throws LightspeedRetailException
Expand Down
3 changes: 2 additions & 1 deletion src/Traits/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ private function buildQueryParameters(array $parameters = []): string
}

if (! is_array($query)) {
$queryParameters[] = $column . $this->_getOperator($this->operator_equal) . urlencode((string)$query);
$query = $column !== 'after' && $column !== 'before' ? urlencode((string) $query) : $query;
$queryParameters[] = $column . $this->_getOperator($this->operator_equal) . $query;

continue;
}
Expand Down

0 comments on commit fd8badf

Please sign in to comment.