Skip to content

Commit

Permalink
Refactored value objects
Browse files Browse the repository at this point in the history
  • Loading branch information
petrknap committed Aug 27, 2024
1 parent 11340c4 commit e98329e
Show file tree
Hide file tree
Showing 36 changed files with 524 additions and 627 deletions.
38 changes: 3 additions & 35 deletions src/ValueObject/Amount.php
Original file line number Diff line number Diff line change
@@ -1,41 +1,9 @@
<?php

namespace ThePay\ApiClient\ValueObject;
declare(strict_types=1);

use InvalidArgumentException;
namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<int>
*/
final class Amount extends BaseValueObject
class Amount extends IntValue
{
/**
* Amount constructor.
*
* @param int $value
*/
public function __construct($value)
{
if ( ! is_int($value)) {
throw new InvalidArgumentException('Value has to be an integer.');
}

$this->value = $value;
}

/**
* @return string
*/
public function __toString()
{
return (string) $this->value;
}

/**
* @return int
*/
public function getValue()
{
return $this->value;
}
}
17 changes: 7 additions & 10 deletions src/ValueObject/BaseValueObject.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace ThePay\ApiClient\ValueObject;

use InvalidArgumentException;
Expand All @@ -15,17 +17,17 @@ abstract class BaseValueObject implements ValueObject
protected $value;

/**
* @param TValue|mixed $value
* @param mixed $value
*
* @throws InvalidArgumentException
*/
public function __construct($value)
final public function __construct($value)
{
$this->value = static::filter($value);
}

/**
* @param TValue|mixed $value
* @param mixed $value
*
* @return static
*
Expand Down Expand Up @@ -57,18 +59,13 @@ public function getValue()
}

/**
* @note should be abstract
*
* @param TValue|mixed $value
* @param mixed $value
*
* @return TValue
*
* @throws InvalidArgumentException
*/
protected static function filter($value)
{
throw self::invalidValue('expected');
}
abstract protected static function filter($value);

protected static function invalidValue(string $expected, ?string $actual = null): InvalidArgumentException
{
Expand Down
37 changes: 10 additions & 27 deletions src/ValueObject/CountryCode.php
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
<?php

declare(strict_types=1);

namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<string>
*/
final class CountryCode extends BaseValueObject
class CountryCode extends NonEmptyString
{
/**
* @param string $value
*/
public function __construct($value)
protected static function filter($value)
{
if ( ! is_string($value) || ! preg_match('/[A-Z]{2}/', $value)) {
throw new \InvalidArgumentException('Value `' . $value . '` is not valid ISO 3166-1 (alpha-2) country code');
}

$this->value = $value;
}
$nonEmptyString = parent::filter($value);
$countryCodeCandidate = trim($nonEmptyString);

/**
* @return string
*/
public function __toString()
{
return $this->value;
}
if (preg_match('/^[A-Z]{2}$/', $countryCodeCandidate) !== 1) {
throw self::invalidValue('ISO 3166-1 (alpha-2) country code', $nonEmptyString);
}

/**
* @return string
*/
public function getValue()
{
return $this->value;
return $countryCodeCandidate;
}
}
41 changes: 9 additions & 32 deletions src/ValueObject/CurrencyCode.php
Original file line number Diff line number Diff line change
@@ -1,43 +1,20 @@
<?php

namespace ThePay\ApiClient\ValueObject;
declare(strict_types=1);

use InvalidArgumentException;
namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<string>
*/
final class CurrencyCode extends BaseValueObject
class CurrencyCode extends NonEmptyString
{
/**
* CurrencyCode constructor.
*
* @param string $value
*/
public function __construct($value)
protected static function filter($value)
{
$value = trim($value);
$nonEmptyString = parent::filter($value);
$currencyCodeCandidate = trim($nonEmptyString);

if (strlen($value) !== 3) {
throw new InvalidArgumentException('Value `' . $value . '` is not valid ISO 4217 currency code');
if (preg_match('/^[A-Z]{3}$/', $currencyCodeCandidate) !== 1) {
throw self::invalidValue('ISO 4217 currency code', $nonEmptyString);
}

$this->value = $value;
}

/**
* @return string
*/
public function __toString()
{
return (string) $this->value;
}

/**
* @return string
*/
public function getValue()
{
return $this->value;
return $currencyCodeCandidate;
}
}
8 changes: 4 additions & 4 deletions src/ValueObject/EmailAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ class EmailAddress extends NonEmptyString
{
public static function filter($value)
{
$nonEmptyString = parent::filter($value);
$emailAddressCandidate = parent::filter($value);

if ((new EmailValidator())->isValid($nonEmptyString, new MultipleValidationWithAnd([
if ((new EmailValidator())->isValid($emailAddressCandidate, new MultipleValidationWithAnd([
new RFCValidation(),
new DNSCheckValidation(),
])) === false) {
throw self::invalidValue('public e-mail address', $nonEmptyString);
throw self::invalidValue('public e-mail address', $emailAddressCandidate);
}

return $nonEmptyString;
return $emailAddressCandidate;
}
}
42 changes: 12 additions & 30 deletions src/ValueObject/EnumValueObject.php
Original file line number Diff line number Diff line change
@@ -1,45 +1,27 @@
<?php

declare(strict_types=1);

namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<string>
* @note all subclasses should be final / you can not inherit from enum
*/
abstract class EnumValueObject extends BaseValueObject
abstract class EnumValueObject extends StringValue
{
/**
* @param string $value
* @return string[]
*/
public function __construct($value)
{
if ( ! in_array($value, static::getOptions(), true)) {
throw new \InvalidArgumentException(sprintf('%s in not valid value', $value));
}
abstract public static function cases(): array;

$this->value = $value;
}

/**
* @return string
*/
public function __toString()
protected static function filter($value)
{
return (string) $this->value;
}
$caseCandidate = parent::filter($value);

/**
* @return string
*/
public function getValue()
{
return $this->value;
}
if ( ! in_array($caseCandidate, static::cases(), true)) {
throw self::invalidValue('case', $caseCandidate);
}

/**
* @return string[]
*/
public static function getOptions()
{
return [];
return $caseCandidate;
}
}
42 changes: 10 additions & 32 deletions src/ValueObject/Identifier.php
Original file line number Diff line number Diff line change
@@ -1,43 +1,21 @@
<?php

namespace ThePay\ApiClient\ValueObject;
declare(strict_types=1);

use InvalidArgumentException;
namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<string>
*/
final class Identifier extends BaseValueObject
class Identifier extends NonEmptyString
{
/**
* Uid constructor.
*
* @param string $value
*/
public function __construct($value)
public const STRLEN_MAX = 100;

protected static function filter($value)
{
$value = trim($value);
$identifierCandidate = trim(parent::filter($value));

if (strlen($value) > 100) {
throw new InvalidArgumentException('Value\'s length has to be up to 100 characters');
if (strlen($identifierCandidate) > self::STRLEN_MAX) {
throw self::invalidValue(sprintf('up to %d characters', self::STRLEN_MAX), $identifierCandidate);
}

$this->value = (string) $value;
}

/**
* @return string
*/
public function __toString()
{
return $this->value;
}

/**
* @return string
*/
public function getValue()
{
return $this->value;
return $identifierCandidate;
}
}
27 changes: 27 additions & 0 deletions src/ValueObject/IntValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace ThePay\ApiClient\ValueObject;

/**
* @extends BaseValueObject<int>
*/
class IntValue extends BaseValueObject
{
public function __toString()
{
return (string) $this->value;
}

protected static function filter($value)
{
$intCandidate = filter_var($value, FILTER_VALIDATE_INT);

if ($intCandidate === false) {
throw self::invalidValue('int');
}

return $intCandidate;
}
}
Loading

0 comments on commit e98329e

Please sign in to comment.