Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endpoint structure change poc #736

Merged
merged 2 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/Contracts/HasBody.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Mollie\Api\Contracts;

interface HasBody
{
/**
* Get the body of the response.
*
* @return string
*/
public function getBody(): string;
}
10 changes: 10 additions & 0 deletions src/Contracts/IsIteratable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Mollie\Api\Contracts;

interface IsIteratable
{
public function iteratorEnabled(): bool;

public function iteratesBackwards(): bool;
}
98 changes: 98 additions & 0 deletions src/Http/BaseEndpointCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Mollie\Api\Http;

use Mollie\Api\Contracts\HasBody;
use Mollie\Api\Http\Request;
use Mollie\Api\Contracts\IsIteratable;
use Mollie\Api\MollieApiClient;
use Mollie\Api\Resources\BaseCollection;
use Mollie\Api\Resources\BaseResource;
use Mollie\Api\Resources\CursorCollection;
use Mollie\Api\Resources\ResourceFactory;

abstract class BaseEndpointCollection
{
/**
* @var MollieApiClient
*/
protected MollieApiClient $client;

public function __construct(MollieApiClient $client)
{
$this->client = $client;
}

public function send(Request $request): mixed
{
$path = $request->resolveResourcePath()
. $this->buildQueryString($request->getQuery());

$body = $request instanceof HasBody
? $request->getBody()
: null;

$result = $this->client->performHttpCall(
$request->getMethod(),
$path,
$body
);

if ($result->isEmpty()) {
return null;
}

$targetResourceClass = $request->getTargetResourceClass();

if (is_subclass_of($targetResourceClass, BaseCollection::class)) {
$collection = $this->buildResultCollection($result->decode(), $targetResourceClass);

if ($request instanceof IsIteratable && $request->iteratorEnabled()) {
/** @var CursorCollection $collection */
return $collection->getAutoIterator($request->iteratesBackwards());
}

return $collection;
}

if (is_subclass_of($targetResourceClass, BaseResource::class)) {
return ResourceFactory::createFromApiResult($this->client, $result->decode(), $targetResourceClass);
}

return null;
}

protected function buildResultCollection(object $result, string $targetCollectionClass): BaseCollection
{
return ResourceFactory::createBaseResourceCollection(
$this->client,
($targetCollectionClass)::getResourceClass(),
$result->_embedded->{$targetCollectionClass::getCollectionResourceName()},
$result->_links,
$targetCollectionClass
);
}

/**
* @param array $filters
* @return string
*/
protected function buildQueryString(array $filters): string
{
if (empty($filters)) {
return "";
}

foreach ($filters as $key => $value) {
if ($value === true) {
$filters[$key] = "true";
}

if ($value === false) {
$filters[$key] = "false";
}
}

return "?" . http_build_query($filters, "", "&");
}
}
20 changes: 20 additions & 0 deletions src/Http/EndpointCollection/BalanceEndpointCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Mollie\Api\Http\EndpointCollection;

use Mollie\Api\Http\BaseEndpointCollection;
use Mollie\Api\Http\Requests\GetPaginatedBalancesRequest;
use Mollie\Api\Resources\BalanceCollection;

class BalanceEndpointCollection extends BaseEndpointCollection
{
/**
* Get the balance endpoint.
*
* @return BalanceEndpoint
*/
public function page(?string $from = null, ?int $limit = null, array $parameters = []): BalanceCollection

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 7.4

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 7.4

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

Method Mollie\Api\Http\EndpointCollection\BalanceEndpointCollection::page() has invalid return type Mollie\Api\Http\EndpointCollection\BalanceEndpoint.

Check failure on line 16 in src/Http/EndpointCollection/BalanceEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @return with type Mollie\Api\Http\EndpointCollection\BalanceEndpoint is not subtype of native type Mollie\Api\Resources\BalanceCollection.
{
return $this->send(new GetPaginatedBalancesRequest($from, $limit, $parameters));
}
}
77 changes: 77 additions & 0 deletions src/Http/EndpointCollection/PaymentEndpointCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Mollie\Api\Http\EndpointCollection;

use Mollie\Api\Http\BaseEndpointCollection;
use Mollie\Api\Http\Requests\GetPaginatedPaymentsRequest;
use Mollie\Api\Http\Requests\GetPaymentRequest;
use Mollie\Api\Http\Requests\RefundPaymentRequest;
use Mollie\Api\Resources\LazyCollection;
use Mollie\Api\Resources\Payment;
use Mollie\Api\Resources\PaymentCollection;
use Mollie\Api\Resources\Refund;

class PaymentEndpointCollection extends BaseEndpointCollection
{
/**
* Get the balance endpoint.
*
* @return PaymentCollection
*/
public function page(?string $from = null, ?int $limit = null, array $filters = []): PaymentCollection
{
return $this->send(new GetPaginatedPaymentsRequest($from, $limit, $filters));
}

/**
* Retrieve a single payment from Mollie.
*
* Will throw a ApiException if the payment id is invalid or the resource cannot be found.
*
* @param string $paymentId
* @param array $filters
*
* @return Payment
* @throws ApiException
*/
public function get(string $paymentId, array $filters = []): Payment

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 7.4

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 37 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable
{
return $this->send(new GetPaymentRequest($paymentId, $filters));
}

/**
* Issue a refund for the given payment.
*
* The $data parameter may either be an array of endpoint parameters, a float value to
* initiate a partial refund, or empty to do a full refund.
*
* @param Payment $payment
* @param array|float|null $data
*
* @return Refund
* @throws ApiException
*/
public function refund(Payment $payment, $data = []): Refund

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 7.4

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.1

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable

Check failure on line 54 in src/Http/EndpointCollection/PaymentEndpointCollection.php

View workflow job for this annotation

GitHub Actions / PHP - 8.3

PHPDoc tag @throws with type Mollie\Api\Http\EndpointCollection\ApiException is not subtype of Throwable
{
return $this->send(new RefundPaymentRequest($payment->id, $data));
}

/**
* Create an iterator for iterating over payments retrieved from Mollie.
*
* @param string $from The first resource ID you want to include in your list.
* @param int $limit
* @param array $filters
* @param bool $iterateBackwards Set to true for reverse order iteration (default is false).
*
* @return LazyCollection
*/
public function iterator(?string $from = null, ?int $limit = null, array $filters = [], bool $iterateBackwards = false): LazyCollection
{
return $this->send(
(new GetPaginatedPaymentsRequest($from, $limit, $filters))
->useIterator()
->setIterationDirection($iterateBackwards)
);
}
}
25 changes: 25 additions & 0 deletions src/Http/EndpointCollection/PaymentRefundEndpointCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Mollie\Api\Http\EndpointCollection;

use Mollie\Api\Http\BaseEndpointCollection;
use Mollie\Api\Http\Requests\GetPaginatedPaymentRefundsRequest;
use Mollie\Api\Resources\RefundCollection;

class PaymentRefundEndpointCollection extends BaseEndpointCollection
{
/**
* @param string $paymentId
* @param array $filters
*
* @return RefundCollection
* @throws \Mollie\Api\Exceptions\ApiException
*/
public function page(string $paymentId, array $filters = []): RefundCollection
{
return $this->send(new GetPaginatedPaymentRefundsRequest(
$paymentId,
$filters
));
}
}
53 changes: 53 additions & 0 deletions src/Http/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Mollie\Api\Http;

use LogicException;

abstract class Request
{
/**
* Define the HTTP method.
*/
protected string $method;

/**
* The resource class the request should be casted to.
*
* @var string
*/
public static string $targetResourceClass;

/**
* Get the method of the request.
*/
public function getMethod(): string
{
if (!isset($this->method)) {
throw new LogicException('Your request is missing a HTTP method. You must add a method property like [protected Method $method = Method::GET]');
}

return $this->method;
}

public function getQuery(): array
{
return [];
}

public static function getTargetResourceClass(): string
{
if (empty(static::$targetResourceClass)) {
throw new \RuntimeException('Resource class is not set.');
}

return static::$targetResourceClass;
}

/**
* Resolve the resource path.
*
* @return string
*/
abstract public function resolveResourcePath(): string;
}
34 changes: 34 additions & 0 deletions src/Http/Requests/GetPaginatedBalancesRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Mollie\Api\Http\Requests;

use Mollie\Api\MollieApiClient;
use Mollie\Api\Http\Request;
use Mollie\Api\Resources\BalanceCollection;

class GetPaginatedBalancesRequest extends Request
{
use IsPaginatedRequest;

/**
* Define the HTTP method.
*/
protected string $method = MollieApiClient::HTTP_GET;

/**
* The resource class the request should be casted to.
*
* @var string
*/
public static string $targetResourceClass = BalanceCollection::class;

/**
* Resolve the resource path.
*
* @return string
*/
public function resolveResourcePath(): string
{
return "balances";
}
}
40 changes: 40 additions & 0 deletions src/Http/Requests/GetPaginatedPaymentRefundsRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Mollie\Api\Http\Requests;

use Mollie\Api\Http\Request;
use Mollie\Api\MollieApiClient;

class GetPaginatedPaymentRefundsRequest extends Request
{
use IsPaginatedRequest;

/**
* Define the HTTP method.
*/
protected string $method = MollieApiClient::HTTP_GET;

/**
* The resource class the request should be casted to.
*
* @var string
*/
public static string $targetResourceClass = \Mollie\Api\Resources\RefundCollection::class;

protected string $paymentId;

public function __construct(
string $paymentId,
array $filters = []
) {
$this->paymentId = $paymentId;
$this->filters = $filters;
}

public function resolveResourcePath(): string
{
$id = urlencode($this->paymentId);

return "payments/{$id}/refunds";
}
}
Loading
Loading