Skip to content

Commit

Permalink
Merge pull request cronofy#97 from basekit/batch
Browse files Browse the repository at this point in the history
Add batch endpoint support
  • Loading branch information
AdamWhittingham authored Apr 16, 2021
2 parents 6043fc3 + 3247248 commit 7274171
Show file tree
Hide file tree
Showing 7 changed files with 792 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/Batch/Batch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php declare(strict_types=1);

namespace Cronofy\Batch;

use Cronofy\Cronofy;

class Batch
{
/** @var BatchRequest[] */
private $requests = [];

public static function create(): self
{
return new self();
}

public function upsertEvent(string $calendarId, array $data): self
{
$path = $this->buildEventsPath($calendarId);

return $this->addPostRequest($path, $data);
}

public function deleteEvent(string $calendarId, string $eventId): self
{
$path = $this->buildEventsPath($calendarId);
$data = ['event_id' => $eventId];

return $this->addDeleteRequest($path, $data);
}

public function updateExternalEvent(string $calendarId, array $data): self
{
$path = $this->buildEventsPath($calendarId);

return $this->addPostRequest($path, $data);
}

public function deleteExternalEvent(string $calendarId, string $eventUid): self
{
$path = $this->buildEventsPath($calendarId);
$data = ['event_uid' => $eventUid];

return $this->addDeleteRequest($path, $data);
}

public function upsertAvailablePeriod(array $data): self
{
$path = $this->buildAvailablePeriodsPath();

return $this->addPostRequest($path, $data);
}

public function deleteAvailablePeriod(string $availablePeriodId): self
{
$path = $this->buildAvailablePeriodsPath();
$data = ['available_period_id' => $availablePeriodId];

return $this->addDeleteRequest($path, $data);
}

private function buildEventsPath(string $calendarId): string
{
return sprintf('/%s/calendars/%s/events', Cronofy::API_VERSION, $calendarId);
}

private function buildAvailablePeriodsPath(): string
{
return sprintf('/%s/available_periods', Cronofy::API_VERSION);
}

private function addPostRequest(string $relativeUrl, array $data): self
{
return $this->addRequest('POST', $relativeUrl, $data);
}

private function addDeleteRequest(string $relativeUrl, array $data): self
{
return $this->addRequest('DELETE', $relativeUrl, $data);
}

private function addRequest(string $method, string $relativeUrl, array $data): self
{
$this->requests[] = new BatchRequest($method, $relativeUrl, $data);

return $this;
}

public function requests(): array
{
return $this->requests;
}
}
32 changes: 32 additions & 0 deletions src/Batch/BatchRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);

namespace Cronofy\Batch;

class BatchRequest
{
private $method;
private $relativeUrl;
private $data;

public function __construct(string $method, string $relativeUrl, array $data)
{
$this->method = $method;
$this->relativeUrl = $relativeUrl;
$this->data = $data;
}

public function method(): string
{
return $this->method;
}

public function relativeUrl(): string
{
return $this->relativeUrl;
}

public function data(): array
{
return $this->data;
}
}
51 changes: 51 additions & 0 deletions src/Batch/BatchResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types=1);

namespace Cronofy\Batch;

class BatchResponse
{
private $status;
private $headers;
private $data;
private $request;

public function __construct(int $status, ?array $headers, ?array $data, BatchRequest $request)
{
$this->status = $status;
$this->headers = $headers;
$this->data = $data;
$this->request = $request;
}

public function status(): int
{
return $this->status;
}

public function hasSuccessStatus(): bool
{
$status = $this->status();

return $status >= 200 && $status < 300;
}

public function hasErrorStatus(): bool
{
return !$this->hasSuccessStatus();
}

public function headers(): ?array
{
return $this->headers;
}

public function data(): ?array
{
return $this->data;
}

public function request(): BatchRequest
{
return $this->request;
}
}
39 changes: 39 additions & 0 deletions src/Batch/BatchResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php declare(strict_types=1);

namespace Cronofy\Batch;

class BatchResult
{
private $responses;
private $errors;

public function __construct(BatchResponse ...$responses)
{
$this->responses = $responses;
}

public function responses(): array
{
return $this->responses;
}

public function errors(): array
{
if ($this->errors === null) {
$this->errors = [];

foreach ($this->responses as $response) {
if ($response->hasErrorStatus()) {
$this->errors[] = $response;
}
}
}

return $this->errors;
}

public function hasErrors(): bool
{
return count($this->errors()) > 0;
}
}
56 changes: 56 additions & 0 deletions src/Cronofy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace Cronofy;

use Cronofy\Batch\BatchRequest;
use Cronofy\Exception\CronofyException;
use Cronofy\Exception\PartialBatchFailureException;
use Cronofy\Http\CurlRequest;
use Cronofy\Batch\Batch;
use Cronofy\Batch\BatchResponse;
use Cronofy\Batch\BatchResult;

class Cronofy
{
Expand Down Expand Up @@ -1028,6 +1033,57 @@ public function conferencingServiceAuthorization($params)
return $this->httpPost("/" . self::API_VERSION . "/conferencing_service_authorizations", $postFields);
}

public function executeBatch(Batch $batch): BatchResult
{
$requests = $batch->requests();

$postFields = [
'batch' => $this->convertBatchRequestsToArray(...$requests),
];

$httpResult = $this->httpPost(
sprintf('/%s/batch', self::API_VERSION),
$postFields
);

$responses = [];

foreach ($httpResult['batch'] as $i => $response) {
$responses[] = new BatchResponse(
$response['status'],
$response['headers'] ?? null,
$response['data'] ?? null,
$requests[$i]
);
}

$result = new BatchResult(...$responses);

if ($result->hasErrors()) {
$errorCount = count($result->errors());

throw new PartialBatchFailureException(
sprintf('Batch contains %d errors', $errorCount),
$result
);
}

return $result;
}

private function convertBatchRequestsToArray(BatchRequest ...$requests): array
{
$requestMapper = function (BatchRequest $request) {
return [
'method' => $request->method(),
'relative_url' => $request->relativeUrl(),
'data' => $request->data(),
];
};

return array_map($requestMapper, $requests);
}

private function apiUrl($path)
{
return $this->apiRootUrl . $path;
Expand Down
23 changes: 23 additions & 0 deletions src/Exception/PartialBatchFailureException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php declare(strict_types=1);

namespace Cronofy\Exception;

use Cronofy\Batch\BatchResult;
use Exception;

class PartialBatchFailureException extends Exception
{
private $result;

public function __construct(string $message, BatchResult $result)
{
$this->result = $result;

parent::__construct($message);
}

public function result(): BatchResult
{
return $this->result;
}
}
Loading

0 comments on commit 7274171

Please sign in to comment.