File: D:/HostingSpaces/farmfun/reserveren.farmfun.be/app/Komma/Teamleader/Base/ResourceFactory.php
<?php
namespace App\Komma\Teamleader\Base;
use Carbon\Carbon;
final class ResourceFactory
{
/**
* The attributes that are directly creatable classes
*
* @var array|string[]
*/
private static array $attributeClasses = [
// OrderLine::class,
// OrderStatus::class,
// PaymentMethod::class,
// Shipment::class,
];
/**
* The attributes that are created through the factory
*
* @var array|string[]
*/
private static array $attributeResourceClasses = [
];
/**
* Create an array of resource objects from API results
*
* @param array $apiResults
* @param string $resourceClass
* @return array
*/
public static function createFromApiResults(array $apiResults, string $resourceClass): array
{
$collection = [];
foreach ($apiResults as $result) {
$collection[] = self::createFromApiResult($result, new $resourceClass);
}
return $collection;
}
/**
* Create resource object from API result
*
* @param object $apiResult
* @param ApiResource $resource
*
* @return ApiResource
*/
public static function createFromApiResult(object $apiResult, ApiResource $resource)
{
$resource->setApiResponse($apiResult);
foreach ($apiResult as $property => $value) {
if ($resource->isSkippableAttribute($property)) {
continue;
}
if (! property_exists($resource, $property)) {
//TODO: Throw error when running test, this should actually not happen...
// debug($apiResult);
debug(self::class.': Undefined property "'.$property.'" on Resource "'.get_class($resource).'"');
// debug('');
continue;
}
// Typed attributes will be handled in the render
if ($resource->isTypeAttribute($property) && isset($value)) {
if (is_array($value)) {
$assets = [];
foreach ($value as $asset) {
$assets[] = self::createTypeAttribute($property, $resource->getTypeOfAttribute($property), $asset);
}
$value = $assets;
} else {
$value = self::createTypeAttribute($property, $resource->getTypeOfAttribute($property), $value);
}
}
// Check if property is a date attribute, then convert it into Carbon
if ($resource->isDateAttribute($property) && $value !== null) {
$value = Carbon::parse($value);
}
$resource->{$property} = $value;
}
return $resource;
}
/**
* Create a typed attribute.
*
* @param string $property
* @param string $attribute
* @param $value
* @return ApiResource|ApiResponse|mixed|null
*/
public static function createTypeAttribute(string $property, string $attribute, $value)
{
if (in_array($attribute, self::$attributeClasses)) {
return new $attribute($value);
}
if (in_array($attribute, self::$attributeResourceClasses)) {
return self::createFromApiResult($value, new $attribute());
}
/**
* Attributes that have special rules for creating
*/
switch ($attribute) {
// case Product::class:
// if(in_array($property, ['alternatives'])) return ResourceFactory::createFromApiResult($value, new Product());
// $apiResponse = new ApiResponse(Product::class);
// return $apiResponse->fill([$value, null]);
}
debug(self::class.': Undefined type attribute resolving "'.$attribute.'"');
return null;
}
}