Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Naoray committed Dec 18, 2024
1 parent ff5ef29 commit 30ed85c
Show file tree
Hide file tree
Showing 10 changed files with 529 additions and 37 deletions.
16 changes: 16 additions & 0 deletions src/Contracts/ResourceDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Mollie\Api\Contracts;

use Mollie\Api\Http\Response;
use Mollie\Api\Resources\BaseCollection;
use Mollie\Api\Resources\BaseResource;
use Mollie\Api\Resources\LazyCollection;

interface ResourceDecorator
{
/**
* @param Response|BaseResource|BaseCollection|LazyCollection $resource
*/
public static function fromResource($resource): self;
}
39 changes: 30 additions & 9 deletions src/Http/Requests/ResourceHydratableRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,63 @@
namespace Mollie\Api\Http\Requests;

use Mollie\Api\Http\Request;
use Mollie\Api\Resources\DecorateResource;

abstract class ResourceHydratableRequest extends Request
{
/**
* The resource class the request should be hydrated into.
* The original resource class the request should be hydrated into.
*
* @var string|null
*/
protected $hydratableResource = null;

/**
* The custom resource class the request should be hydrated into.
*
* @var string|null|DecorateResource
*/
protected ?string $customHydratableResource = null;

Check failure on line 22 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

PHPDoc tag @var for property Mollie\Api\Http\Requests\ResourceHydratableRequest::$customHydratableResource with type Mollie\Api\Resources\DecorateResource|string|null is not subtype of native type string|null.

Check failure on line 22 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.4

PHPDoc tag @var for property Mollie\Api\Http\Requests\ResourceHydratableRequest::$customHydratableResource with type Mollie\Api\Resources\DecorateResource|string|null is not subtype of native type string|null.

public function isHydratable(): bool
{
return $this->hydratableResource !== null;
return $this->hydratableResource !== null || $this->customHydratableResource !== null;
}

public function getHydratableResource(): string
/**
* @return string|DecorateResource
*/
public function getHydratableResource()
{
if (! $this->isHydratable()) {
throw new \RuntimeException('Resource class is not set.');
}

return $this->hydratableResource;
return $this->customHydratableResource ?? $this->hydratableResource;
}

public function setHydratableResource(string $hydratableResource): self
/**
* @param string|DecorateResource $hydratableResource
* @return self
*/
public function setHydratableResource($hydratableResource): self
{
if (! class_exists($hydratableResource)) {
throw new \InvalidArgumentException("The resource class '{$hydratableResource}' does not exist.");
}

/** @phpstan-ignore-next-line */
if ($this->hydratableResource && ! is_subclass_of($hydratableResource, $this->hydratableResource)) {
throw new \InvalidArgumentException("The resource class '{$hydratableResource}' does not match the existing resource class '{$this->hydratableResource}'.");
if ($hydratableResource instanceof DecorateResource && ! $hydratableResource->getDecorator()) {

Check failure on line 51 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

Instanceof between class-string and Mollie\Api\Resources\DecorateResource will always evaluate to false.

Check failure on line 51 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

Result of && is always false.

Check failure on line 51 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.4

Instanceof between class-string and Mollie\Api\Resources\DecorateResource will always evaluate to false.

Check failure on line 51 in src/Http/Requests/ResourceHydratableRequest.php

View workflow job for this annotation

GitHub Actions / PHP - 8.4

Result of && is always false.
throw new \InvalidArgumentException("The decorator class is not set.");
}

$this->hydratableResource = $hydratableResource;
$this->customHydratableResource = $hydratableResource;

return $this;
}

public function resetHydratableResource(): self
{
$this->customHydratableResource = null;

return $this;
}
Expand Down
38 changes: 38 additions & 0 deletions src/Resources/DecorateResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Mollie\Api\Resources;

use Mollie\Api\Contracts\ResourceDecorator;

class DecorateResource
{
protected string $decoratedResource;

protected ?string $decorator = null;

public function __construct(string $decoratedResource)
{
$this->decoratedResource = $decoratedResource;
}

public function with(string $decorator): self
{
if (! is_subclass_of($decorator, ResourceDecorator::class)) {
throw new \InvalidArgumentException("The decorator class '{$decorator}' does not implement the DecoratedResource interface.");
}

$this->decorator = $decorator;

return $this;
}

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

public function getDecorator(): ?string
{
return $this->decorator;
}
}
2 changes: 1 addition & 1 deletion src/Resources/Onboarding.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function needsData(): bool
return $this->status === OnboardingStatus::NEEDS_DATA;
}

public function isInReview(): bool
public function inReview(): bool
{
return $this->status === OnboardingStatus::IN_REVIEW;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/ResourceCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ abstract class ResourceCollection extends BaseCollection
public static function getResourceClass(): string
{
if (empty(static::$resource)) {
throw new \RuntimeException('Collection name not set');
throw new \RuntimeException('Resource name not set');
}

return static::$resource;
Expand Down
57 changes: 37 additions & 20 deletions src/Resources/ResourceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Mollie\Api\Resources;

use Mollie\Api\Contracts\Connector;
use Mollie\Api\Contracts\ResourceDecorator;
use Mollie\Api\Contracts\EmbeddedResourcesContract;
use Mollie\Api\Exceptions\EmbeddedResourcesNotParseableException;
use Mollie\Api\Http\Response;
Expand Down Expand Up @@ -37,6 +38,42 @@ public static function createFromApiResult(Connector $connector, $data, string $
return $resource;
}

/**
* @param null|array|\ArrayObject $data
*/
public static function createBaseResourceCollection(
Connector $connector,
string $resourceClass,
Response $response,
$data = null,
?object $_links = null,
?string $resourceCollectionClass = null
): BaseCollection {
return self::instantiateBaseCollection(
$connector,
self::determineCollectionClass($resourceClass, $resourceCollectionClass),
self::mapToResourceObjects($connector, $data ?? [], $resourceClass, $response),
$response,
$_links
);
}

/**
* Create a decorated resource from a response or existing resource.
*
* @param Response|BaseResource|BaseCollection|LazyCollection $response
* @param string $decorator
* @return ResourceDecorator
*/
public static function createDecoratedResource($response, string $decorator): ResourceDecorator
{
if (! is_subclass_of($decorator, ResourceDecorator::class)) {
throw new \InvalidArgumentException("The decorator class '{$decorator}' does not implement the ResourceDecorator interface.");
}

return $decorator::fromResource($response);
}

/**
* Check if the resource holds embedded resources
*
Expand Down Expand Up @@ -105,26 +142,6 @@ private static function createEmbeddedResourceCollection(
);
}

/**
* @param null|array|\ArrayObject $data
*/
public static function createBaseResourceCollection(
Connector $connector,
string $resourceClass,
Response $response,
$data = null,
?object $_links = null,
?string $resourceCollectionClass = null
): BaseCollection {
return self::instantiateBaseCollection(
$connector,
self::determineCollectionClass($resourceClass, $resourceCollectionClass),
self::mapToResourceObjects($connector, $data ?? [], $resourceClass, $response),
$response,
$_links
);
}

private static function instantiateBaseCollection(
Connector $connector,
string $collectionClass,
Expand Down
10 changes: 10 additions & 0 deletions src/Resources/ResourceHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ public function hydrate(ResourceHydratableRequest $request, Response $response)
{
$targetResourceClass = $request->getHydratableResource();

if ($targetResourceClass instanceof DecorateResource) {
$response = $this->hydrate(
// Reset the hydratable resource to the original resource class.
$request->resetHydratableResource(),
$response,
);

return ResourceFactory::createDecoratedResource($response, $targetResourceClass->getDecorator());

Check failure on line 28 in src/Resources/ResourceHydrator.php

View workflow job for this annotation

GitHub Actions / PHP - 8.2

Method Mollie\Api\Resources\ResourceHydrator::hydrate() should return Mollie\Api\Http\Response|Mollie\Api\Resources\BaseCollection|Mollie\Api\Resources\BaseResource|Mollie\Api\Resources\LazyCollection but returns Mollie\Api\Contracts\ResourceDecorator.

Check failure on line 28 in src/Resources/ResourceHydrator.php

View workflow job for this annotation

GitHub Actions / PHP - 8.4

Method Mollie\Api\Resources\ResourceHydrator::hydrate() should return Mollie\Api\Http\Response|Mollie\Api\Resources\BaseCollection|Mollie\Api\Resources\BaseResource|Mollie\Api\Resources\LazyCollection but returns Mollie\Api\Contracts\ResourceDecorator.
}

if ($this->isCollectionTarget($targetResourceClass)) {
$collection = $this->buildResultCollection($response, $targetResourceClass);

Expand Down
6 changes: 3 additions & 3 deletions tests/Resources/OnboardingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public function dpTestOnboardingStatuses()
{
return [
[OnboardingStatus::NEEDS_DATA, 'needsData', true],
[OnboardingStatus::NEEDS_DATA, 'isInReview', false],
[OnboardingStatus::NEEDS_DATA, 'inReview', false],
[OnboardingStatus::NEEDS_DATA, 'isCompleted', false],

[OnboardingStatus::IN_REVIEW, 'needsData', false],
[OnboardingStatus::IN_REVIEW, 'isInReview', true],
[OnboardingStatus::IN_REVIEW, 'inReview', true],
[OnboardingStatus::IN_REVIEW, 'isCompleted', false],

[OnboardingStatus::COMPLETED, 'needsData', false],
[OnboardingStatus::COMPLETED, 'isInReview', false],
[OnboardingStatus::COMPLETED, 'inReview', false],
[OnboardingStatus::COMPLETED, 'isCompleted', true],
];
}
Expand Down
Loading

0 comments on commit 30ed85c

Please sign in to comment.