Skip to content

Commit

Permalink
feat: add estate repository builder query
Browse files Browse the repository at this point in the history
  • Loading branch information
Katalam committed May 12, 2024
1 parent 4f1ecd6 commit d1fd272
Show file tree
Hide file tree
Showing 9 changed files with 644 additions and 53 deletions.
3 changes: 2 additions & 1 deletion src/Facades/EstateRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
namespace Katalam\OnOfficeAdapter\Facades;

use Illuminate\Support\Facades\Facade;
use Katalam\OnOfficeAdapter\Query\EstateBuilder;

/**
* @see \Katalam\OnOfficeAdapter\Repositories\EstateRepository
*
* @method static all()
* @method EstateBuilder query()
*/
class EstateRepository extends Facade
{
Expand Down
126 changes: 126 additions & 0 deletions src/Query/Builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

namespace Katalam\OnOfficeAdapter\Query;

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Conditionable;

abstract class Builder
{
use Conditionable;

/**
* An array of columns to be selected.
*/
public array $columns = [];

/**
* An array of filters.
*/
public array $filters = [];

/**
* The limit for the query.
*/
public int $limit = 500;

/**
* An array of columns to order by.
* Each element should be an array with the column name and the direction.
*/
public array $orderBy = [];

/**
* The offset for the query.
*/
public int $offset = 0;

public function select(array|string $columns = ['ID']): self
{
$this->columns = Arr::wrap($columns);

return $this;
}

public function addSelect(array|string $column): self
{
$column = Arr::wrap($column);

$this->columns = array_merge($this->columns, $column);

return $this;
}

public function orderBy(string $column, string $direction = 'asc'): self
{
$direction = Str::upper($direction);

$this->orderBy[] = [$column, $direction];

return $this;
}

public function orderByDesc(string $column): self
{
return $this->orderBy($column, 'desc');
}

public function offset(int $value): self
{
$this->offset = max(0, $value);

return $this;
}

public function limit(int $value): self
{
$this->limit = max(0, $value);

return $this;
}

public function where(string $column, mixed $operator, mixed $value = null): self
{
if (is_null($value)) {
$value = $operator;
$operator = '=';
}

$this->filters[] = [$column, $operator, $value];

return $this;
}

protected function getFilters(): array
{
return collect($this->filters)->mapWithKeys(function ($value) {
[$column, $operator, $value] = $value;

return [
$column => [
'op' => $operator,
'val' => $value,
],
];
})->toArray();
}

protected function getOrderBy(): array
{
return collect($this->orderBy)->mapWithKeys(function ($value) {
[$column, $direction] = $value;

return [
$column => $direction,
];
})->toArray();
}

abstract public function get(): Collection;

abstract public function first(): array;

abstract public function find(int $id): array;
}
88 changes: 88 additions & 0 deletions src/Query/EstateBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

namespace Katalam\OnOfficeAdapter\Query;

use Illuminate\Support\Collection;
use Katalam\OnOfficeAdapter\Enums\OnOfficeAction;
use Katalam\OnOfficeAdapter\Enums\OnOfficeResourceType;
use Katalam\OnOfficeAdapter\Exceptions\OnOfficeException;
use Katalam\OnOfficeAdapter\Services\OnOfficeService;

class EstateBuilder extends Builder
{
public function __construct(
private readonly OnOfficeService $onOfficeService,
) {
}

public function get(): Collection
{
$columns = $this->columns;
$filter = $this->getFilters();
$listLimit = $this->limit;
$listOffset = $this->offset;
$orderBy = $this->getOrderBy();

return $this->onOfficeService->requestAll(/**
* @throws OnOfficeException
*/ function (int $pageSize, int $offset) use ($filter, $orderBy, $columns) {
return $this->onOfficeService->requestApi(
OnOfficeAction::Read,
OnOfficeResourceType::Estate,
parameters: [
OnOfficeService::DATA => $columns,
OnOfficeService::FILTER => $filter,
OnOfficeService::LISTLIMIT => $pageSize,
OnOfficeService::LISTOFFSET => $offset,
OnOfficeService::SORTBY => $orderBy,

]
);
}, pageSize: $listLimit, offset: $listOffset);
}

/**
* @throws OnOfficeException
*/
public function first(): array
{
$columns = $this->columns;
$filter = $this->getFilters();
$listLimit = $this->limit;
$listOffset = $this->offset;
$orderBy = $this->getOrderBy();

$response = $this->onOfficeService->requestApi(
OnOfficeAction::Read,
OnOfficeResourceType::Estate,
parameters: [
OnOfficeService::DATA => $columns,
OnOfficeService::FILTER => $filter,
OnOfficeService::LISTLIMIT => $listLimit,
OnOfficeService::LISTOFFSET => $listOffset,
OnOfficeService::SORTBY => $orderBy,
]
);

return $response->json('response.results.0.data.records.0');
}

/**
* @throws OnOfficeException
*/
public function find(int $id): array
{
$columns = $this->columns;

$response = $this->onOfficeService->requestApi(
OnOfficeAction::Get,
OnOfficeResourceType::Estate,
$id,
parameters: [
OnOfficeService::DATA => $columns,
]
);

return $response->json('response.results.0.data.records.0');
}
}
23 changes: 4 additions & 19 deletions src/Repositories/EstateRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

namespace Katalam\OnOfficeAdapter\Repositories;

use Illuminate\Support\Collection;
use Katalam\OnOfficeAdapter\Enums\OnOfficeAction;
use Katalam\OnOfficeAdapter\Enums\OnOfficeResourceType;
use Katalam\OnOfficeAdapter\Exceptions\OnOfficeException;
use Katalam\OnOfficeAdapter\Query\EstateBuilder;
use Katalam\OnOfficeAdapter\Services\OnOfficeService;

readonly class EstateRepository
Expand All @@ -16,22 +13,10 @@ public function __construct(
}

/**
* Requests all estates from the onOffice API with a paginated request.
* Returns a new estate builder instance.
*/
public function all(): Collection
public function query(): EstateBuilder
{
return $this->onOfficeService->requestAll(/**
* @throws OnOfficeException
*/ function (int $pageSize, int $offset) {
return $this->onOfficeService->requestApi(
OnOfficeAction::Read,
OnOfficeResourceType::Estate,
parameters: [
OnOfficeService::DATA => ['Id'],
OnOfficeService::LISTLIMIT => $pageSize,
OnOfficeService::LISTOFFSET => $offset,
]
);
});
return new EstateBuilder($this->onOfficeService);
}
}
33 changes: 24 additions & 9 deletions src/Services/OnOfficeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class OnOfficeService

public const LISTOFFSET = 'listoffset';

public const FILTER = 'filter';

public const SORTBY = 'sortby';

private string $token;

private string $secret;
Expand Down Expand Up @@ -84,7 +88,7 @@ private function getHmac(OnOfficeAction $actionId, OnOfficeResourceType $resourc
public function requestApi(
OnOfficeAction $actionId,
OnOfficeResourceType $resourceType,
OnOfficeResourceId $resourceId = OnOfficeResourceId::None,
OnOfficeResourceId|string|int $resourceId = OnOfficeResourceId::None,
string|int $identifier = '',
array $parameters = [],
): Response {
Expand All @@ -95,7 +99,7 @@ public function requestApi(
'actions' => [
[
'actionid' => $actionId->value,
'resourceid' => $resourceId->value,
'resourceid' => $resourceId instanceof OnOfficeResourceId ? $resourceId->value : $resourceId,
'resourcetype' => $resourceType->value,
'identifier' => $identifier,
'timestamp' => Carbon::now()->timestamp,
Expand All @@ -107,8 +111,8 @@ public function requestApi(
],
]);

if ($response->json('status.code') !== 200) {
throw new OnOfficeException('Failed to request OnOffice API');
if ($this->responseIsFailed($response)) {
throw new OnOfficeException($response->json('status.message'));
}

return $response;
Expand All @@ -124,16 +128,16 @@ public function requestAll(
callable $request,
string $resultPath = 'response.results.0.data.records',
string $countPath = 'response.results.0.data.meta.cntabsolute',
int $pageSize = 200,
int $pageSize = 500,
int $offset = 0
): Collection {
$maxPage = 0;
$data = collect();
do {
$response = $request($pageSize, $offset);

if ($response->json('status.code') !== 200) {
Log::error('Failed to request estates from onOffice API');
try {
$response = $request($pageSize, $offset);
} catch (OnOfficeException $exception) {
Log::error($exception->getMessage());

return $data;
}
Expand All @@ -155,4 +159,15 @@ public function requestAll(

return $data;
}

/**
* Returns true if the response has a status code greater than 300
* inside the status dot code key in the response.
*/
private function responseIsFailed(Response $response): bool
{
$statusCode = $response->json('status.code', 500);

return $statusCode >= 300;
}
}
Loading

0 comments on commit d1fd272

Please sign in to comment.