File: /home4/cca63905/public_html/nueva/modules/wnetsecurity/src/Api/Resource/ApiResource.php
<?php
/**
* Copyright since 2014 Waynet Sp. z o.o.
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@waynet.pl so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop-project.org/ for more information.
*
* @author Waynet Sp. z o.o. <kontakt@waynet.pl>
* @copyright since 2014 Waynet Sp. z o.o.
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*/
declare(strict_types=1);
namespace Waynet\Security\Api\Resource;
abstract class ApiResource implements \JsonSerializable
{
/**
* Format accepted by date() used to cast datetime fields.
*/
public const DATE_FORMAT = \DATE_ATOM;
/**
* @var array
*/
protected $attributes = [];
/**
* Attribute cast types.
*
* @var string[]
*/
protected const CASTS = [];
/**
* @param array $data attributes
*/
public function __construct(array $data = [])
{
$this->mergeAttributes($data);
}
/**
* Dynamically retrieve attributes on the resource.
*
* @return mixed
*/
public function __get(string $key)
{
return $this->getAttribute($key);
}
/**
* Dynamically set attributes on the resource.
*/
public function __set(string $key, $value)
{
$this->setAttribute($key, $value);
}
public function __isset(string $key): bool
{
return isset($this->attributes[$key]);
}
/**
* Determine if the specified key is an attribute for the resource.
*/
public function hasAttribute(string $key): bool
{
return array_key_exists($key, $this->attributes);
}
/**
* Retrieve an attribute on the resource.
*
* @return mixed
*/
public function getAttribute(string $key)
{
return $this->attributes[$key] ?? null;
}
/**
* Set an attribute on the resource.
*
* @return static
*/
public function setAttribute(string $key, $value): self
{
if (null !== $value && $this->castsAttribute($key)) {
$value = $this->castAs($value, $this->getAttributeCastType($key));
}
$this->attributes[$key] = $value;
return $this;
}
/**
* Overwrite attribute values.
*
* @param array $attributes values to set
* @param bool $clear remove all previous data
*
* @return static
*/
public function setAttributes(array $attributes, bool $clear = false): self
{
if ($clear) {
$this->attributes = [];
}
return $this->mergeAttributes($attributes);
}
/**
* Merge attribute values into the attributes array.
*
* @return static
*/
public function mergeAttributes(array $attributes): self
{
foreach ($attributes as $key => $value) {
$this->setAttribute($key, $value);
}
return $this;
}
/**
* Determine if the specified attribute should be cast.
*/
public function castsAttribute(string $key): bool
{
return array_key_exists($key, $this->getCastTypes());
}
/**
* Get the cast type for the specified attribute.
*/
public function getAttributeCastType(string $key): ?string
{
$castTypes = $this->getCastTypes();
return $castTypes[$key] ?? null;
}
protected function getCastTypes(): array
{
return static::CASTS;
}
/**
* Cast value as a datetime with no time component.
*
* @param string|int $value
*/
protected function castAsDate($value): ?\DateTimeImmutable
{
if (null === $datetime = $this->castAsDateTime($value)) {
return null;
}
return $datetime->setTime(0, 0);
}
/**
* @param string|int $value
*/
protected function castAsDateTime($value): ?\DateTimeImmutable
{
if (null === $value) {
return null;
}
$timestamp = $value;
if (
!is_int($timestamp)
&& false === $timestamp = strtotime($value)
) {
throw new \InvalidArgumentException(sprintf('Unrecognized date format: "%s"', $value));
}
return (new \DateTimeImmutable())->setTimestamp($timestamp);
}
/**
* Cast value to an ApiResource object instance.
*
* @param mixed $value
* @param class-string<ApiResource> $type
*
* @return ApiResource[]|ApiResource|null
*/
protected function castAsClass($value, string $type)
{
if ('[]' === substr($type, -2)) {
$collection = true;
$type = substr($type, 0, -2);
} else {
$collection = false;
}
if (!class_exists($type) || !is_subclass_of($type, self::class)) {
return $collection ? [] : null;
}
return $collection ? $type::castMany($value) : $type::cast($value);
}
protected function castAs($value, string $type)
{
switch ($type) {
case 'bool':
return (bool) $value;
case 'date':
return $this->castAsDate($value);
case 'datetime':
return $this->castAsDateTime($value);
case 'float':
return (float) $value;
case 'int':
return (int) $value;
case 'string':
return (string) $value;
default:
return $this->castAsClass($value, $type);
}
}
/**
* Create a new ApiResource instance from JSON data.
*
* @return static
*/
public static function fromJson(string $data): self
{
return new static(json_decode($data, true));
}
/**
* Get id field key.
*/
public static function getIdField(): string
{
return 'id';
}
/**
* Get id field value.
*
* @return int|string
*/
public function getId()
{
return $this->getAttribute(static::getIdField());
}
/**
* Create new ApiResource instance from raw data.
*
* @param array|\stdClass $data
*
* @return static
*/
public static function cast($data): self
{
return new static((array) $data);
}
/**
* Create new ApiResource instances from raw data.
*
* @param array[]|\stdClass[] $data
*
* @return static[]
*/
public static function castMany(array $data): array
{
return array_map([static::class, 'cast'], $data);
}
public function jsonSerialize(): array
{
return $this->toArray();
}
public function toArray(): array
{
$array = [];
foreach ($this->attributes as $key => $value) {
$array[$key] = $this->serializeAttribute($value);
}
return $array;
}
/** @return mixed */
protected function serializeAttribute($value)
{
if (is_array($value)) {
$value = array_map([$this, 'serializeAttribute'], $value);
} elseif ($value instanceof \DateTimeInterface) {
$value = $value->format(static::DATE_FORMAT);
} elseif (is_object($value) && method_exists($value, 'toArray')) {
$value = $value->toArray();
}
return $value;
}
}