SmartEmailing \ Types
Missing data types for PHP 7.1. Highly extendable.
Neverending data validation can be tiresome. Either you have to validate your data over and over again in every function you use it, or you have to rely it has already been validated somewhere else and risk potential errors. Smelly, right?
Replacing validation hell with Types will make your code much more readable and less vulnerable to bugs.
Types wrap your data in value objects that are guaranteed to be valid and normalized; or not to exist at all. It allows you to use specific type hints instead of primitive types or arrays. Your code will be unbreakable and your IDE will love it.
Table of Contents
- SmartEmailing \ Types
Installation
The recommended way to install is via Composer:
composer require smartemailing/types
How does it work
It is easy. You just initialize desired value object by simple one-liner.
From this point, you have sanitized, normalized and valid data; or SmartEmailing\Types\InvalidTypeException
to handle.
Types consist from:
- String-extractable types - validated strings (E-mail address, Domains, Hexadecimal strings, ...)
- Int-extractable types - validated integers (Port)
- Float-extractable types - validated floats (SigmoidValue, Part, ...)
- Enum-extractable types - enumerables (CountryCode, CurrencyCode, GDPR's Lawful purpose, ...)
- Composite (Array-extractable) types - structures containing multiple another types (Address, ...)
- DateTimes - extraction of DateTime and DateTimeImmutable
- Primitive types extractors and unique arrays
Different types provide different methods related to them, but all types share this extraction API:
Wrapping raw value
<?php
declare(strict_types = 1);
use SmartEmailing\Types\Emailaddress;
use SmartEmailing\Types\InvalidTypeException;
// Valid input
$emailaddress = Emailaddress::from('hello@gmail.com'); // returns Emailaddress object
$emailaddress = Emailaddress::from($emailaddress); // returns original $emailaddress
// Invalid input
$emailaddress = Emailaddress::from('bla bla'); // throws InvalidTypeException
$emailaddress = Emailaddress::from(1); // throws InvalidTypeException
$emailaddress = Emailaddress::from(false); // throws InvalidTypeException
$emailaddress = Emailaddress::from(null); // throws InvalidTypeException
$emailaddress = Emailaddress::from([]); // throws InvalidTypeException
$emailaddress = Emailaddress::from(new \StdClass()); // throws InvalidTypeException
// Nullables
$emailaddress = Emailaddress::fromOrNull(null); // returns NULL
$emailaddress = Emailaddress::fromOrNull('bla bla'); // throws InvalidTypeException
$emailaddress = Emailaddress::fromOrNull('bla bla', true); // returns null instead of throwing
Extraction from array
This is really useful for strict-typing (validation) multidimensional arrays like API requests, forms or database data.
<?php
use SmartEmailing\Types\Emailaddress;
use SmartEmailing\Types\InvalidTypeException;
$input = [
'emailaddress' => 'hello@gmail.com',
'already_types_emailaddress' => Emailaddress::from('hello2@gmail.com'),
'invalid_data' => 'bla bla',
];
// Valid input
$emailaddress = Emailaddress::extract($input, 'emailaddress'); // returns Emailaddress object
$emailaddress = Emailaddress::extract($input, 'already_types_emailaddress'); // returns original Emailaddress object
// Invalid input
$emailaddress = Emailaddress::extract($input, 'invalid_data'); // throws InvalidTypeException
$emailaddress = Emailaddress::extract($input, 'not_existing_key'); // throws InvalidTypeException
// Nullables
$emailaddress = Emailaddress::extractOrNull($input, 'not_existing_key'); // returns null
$emailaddress = Emailaddress::extractOrNull($input, 'invalid_data'); // throws InvalidTypeException
$emailaddress = Emailaddress::extractOrNull($input, 'invalid_data', true); // returns null instead of throwing
// Default values
$emailaddress
= Emailaddress::extractOrNull($input, 'not_existing_key')
?? Emailaddress::from('default@domain.com');
// uses null coalescing operator to assign default value if key not present or null
$emailaddress
= Emailaddress::extractOrNull($input, 'not_existing_key', true)
?? Emailaddress::from('default@domain.com');
// uses null coalescing operator to assign default value if key not present or null or invalid
String-extractable types
String-extractable types are based on validated strings. All values are trimmed before validation.
They can be easily converted back to string by string-type casting or calling $type->getValue()
.
E-mail address
SmartEmailing\Types\Emailaddress
Lowercased and ASCII-transformed e-mail address (hello@gmail.com
)
Type-specific methods:
getLocalPart() : string
returns local part of e-mail address (hello
)getDomain() : \SmartEmailing\Types\Domain
returns domain part (gmail.com
, represented asTypes\Domain
)
Domain
SmartEmailing\Types\Domain
Lowercased domain name (mx1.googlemx.google.com
)
Type-specific methods:
getSecondLevelDomain() : \SmartEmailing\Types\Domain
returns second-level domain. (google.com
)
Hex 32
SmartEmailing\Types\Hex32
Lowercased 32-characters long hexadecimal string useful as container for MD5 or UUID without dashes. (741ecf779c9244358e6b85975bd13452
)
GUID
SmartEmailing\Types\Guid
Lowercased Guid with dashes (741ecf77-9c92-4435-8e6b-85975bd13452
)
IP address
SmartEmailing\Types\IpAddress
IP address v4 or v6. (127.0.0.1
, [2001:0db8:0a0b:12f0:0000:0000:0000:0001]
, 2001:db8:a0b:12f0::1
)
Type-specific methods:
getVersion() : int
returns IP address version,4
or6
URL
SmartEmailing\Types\UrlType
URL based on Nette\Http\Url
(https://www.google.com/search?q=all+work+and+no+play+makes+jack+a+dull+boy
)
Type-specific methods:
getAuthority() : string
returns authority (www.google.com
)getHost() : string
returns Host (www.google.com
)getQueryString() : string
returns Query string (q=all%20work%20and%20no%20play%20makes%20jack%20a%20dull%20boy
)getPath() : string
returns URl Path (/search
)getAbsoluteUrl() : string
Complete URL asstring
, alias forgetValue()
getQueryParameter(string $name, mixed $default = null): mixed
Return value of parameter$name
getBaseUrl(): string
Return URL without path, query string and hash part (https://www.google.cz/
)getScheme(): string
Return URL scheme (https
)hasParameters(string[] $names): bool
Returnstrue
if URL parameters contain all parameters defined in$names
arraygetParameters(): array
Returns all URL parameters as string-indexed arraywithQueryParameter(string $name, mixed $value): UrlType
Returns new instance with added query parameter.
Company registration number
SmartEmailing\Types\CompanyRegistrationNumber
Whitespace-free company registration number for following countries:
CZ
, SK
, CY
Phone number
SmartEmailing\Types\PhoneNumber
Whitespace-free phone number in international format for following countries:
CZ
, SK
, AT
, BE
, FR
, HU
, GB
, DE
, US
, PL
, IT
, SE
, SI
, MH
, NL
, CY
, IE
, DK
, FI
, LU
, TR
Type-specific methods:
getCountry() : SmartEmailing\Types\Country
Originating country (CZ
)
ZIP code
SmartEmailing\Types\ZipCode
Whitespace-free ZIP code valid in following countries:
CZ
, SK
, UK
, US
JSON
SmartEmailing\Types\JsonString
Valid JSON-encoded data as string
Type-specific methods:
static encode(mixed $data) : SmartEmailing\Types\JsonString
create JsonString from raw datagetDecodedValue() : mixed
decode JsonString back to raw data
Base 64
SmartEmailing\Types\Base64String
Valid Base 64-encoded data as string
Type-specific methods:
static encode(string $value) : SmartEmailing\Types\Base64String
create Base64String from stringgetDecodedValue() : string
decode Base64String back to original string
Iban
SmartEmailing\Types\Iban
Type-specific methods:
getFormatted(string $type = SmartEmailing\Types\Iban::FORMAT_ELECTRONIC): string
returns formatted Iban string. Format types:FORMAT_ELECTRONIC
,FORMAT_PRINT
.getCountry(): SmartEmailing\Types\Country
getChecksum(): int
SwiftBic
SmartEmailing\Types\SwiftBic
Valid Swift/Bic codes.
VatId
SmartEmailing\Types\VatId
Type-specific methods:
static isValid(string $vatId): bool
returns true if the vat id is valid otherwise returns falsegetCountry(): ?Country
returnsCountry
under which the subject should falls or null.getPrefix(): ?string
returns string that prefixing vat id likeEL
fromEL123456789
or null.getVatNumber(): string
returns vat number without prefix like123456789
getValue(): string
return whole vat idEL123456789
CurrencyCode
SmartEmailing\Types\CurrencyCode
Valid currency codes by ISO 4217
CountryCode
SmartEmailing\Types\CountryCode
Valid country codes by ISO 3166-1 alpha-2
Int-extractable types
Int-extractable types are based on validated integers.
They can be easily converted back to int by int-type casting or calling $type->getValue()
.
Port
SmartEmailing\Types\Port
Port number
Integer interval, <0, 65535>
Float-extractable types
Float-extractable types are based on validated floats.
They can be easily converted back to float by float-type casting or calling $type->getValue()
.
Part
SmartEmailing\Types\Part
Portion of the whole
Float interval <0.0, 1.0>
Type-specific methods:
static fromRatio(float $value, float $whole): Part
creates new instance by division$value
and$whole
.getPercent(): float
returns(Ratio's value) * 100
to get percent representation
Sigmoid function value
SmartEmailing\Types\SigmoidValue
Result of Sigmoid function, useful when building neural networks.
Float interval <-1.0, 1.0>
.
Rectified Linear Unit function value
SmartEmailing\Types\ReLUValue
Result of Rectified Linear Unit function, useful when building neural networks.
Float interval <0.0, Infinity)
.
Array-extractable types
Array-extractable types are composite types encapsulating one or more another types.
They are created from associative array. All Array-extractable types implement method
toArray() : array
which returns normalized array or type's data.
DateTimeRange
SmartEmailing\Types\DateTimeRange
Range between two \DateTimeInterface
s
Can be created from:
DateTimeRange::from(
[
'from' => 'YYYY-MM-DD HH:MM:SS',
'to' => 'YYYY-MM-DD HH:MM:SS',
]
)
Type-specific methods:
getFrom(): \DateTimeImmutable
returnsFrom
date and time as\DateTimeImmutable
instancegetTo(): \DateTimeImmutable
returnsTo
date and time as\DateTimeImmutable
instancegetDurationInSeconds(): int
returns number of seconds betweenFrom
andTo
datescontains(\DateTimeInterface $dateTime): bool
returnstrue
if provided\DateTimeInterface
lies betweenFrom
andTo
dates.
Duration
SmartEmailing\Types\Duration
Human-readable time interval.
Can be created from:
Duration::from(
[
'value' => 1,
'unit' => TimeUnit::HOURS,
]
);
Type-specific methods:
getDateTimeModify(): string
returns string that is compatible with\DateTime::modify()
and\DateTimeImmutable::modify()
getUnit(): TimeUnit
returnsTimeUnit
enum typegetValue() int
returns number of unitsstatic fromDateTimeModify(string $dateTimeModify): self
creates new instance from string compatible with\DateTime::modify()
and\DateTimeImmutable::modify()
Address
SmartEmailing\Types\Address
Location address cotaining street and number, town, zip code and country.
Can be created from:
Address::from(
[
'street_and_number' => '29 Neibolt Street',
'town' => 'Derry',
'zip_code' => '03038',
'country' => 'US',
]
);
Type-specific methods:
getStreetAndNumber(): string
returns street and numbergetTown(): string
returns TowngetZipCode(): ZipCode
returns ZipCode instancegetCountry(): CountryCode
returns CountryCode instance
Price
SmartEmailing\Types\Price
Price object containing number of currency units with VAT, number of currency units without VAT and currency.
Can be created from:
Price::from(
[
'with_vat' => 432.1,
'without_vat' => 123.45,
'currency' => CurrencyCode::EUR,
]
);
Type-specific methods:
getWithoutVat(): float
returns price without VATgetWithVat(): float
returns price with VATgetCurrency(): CurrencyCode
returns CurrencyCode instance
Array-types
Types
provide another kind of Array-extractable types: Unique primitive-type arrays.
Their purpose is to hold unique set of primitives.
They implement \Countable
and \IteratorAggregate
and natively support
set operations.
All Array-types share following features:
static empty() : self
Creates new empty instance of desired array-type.split(int $chunkSize): self[]
Splits current instance into array of several instances, each with maximum data-set size of$chunkSize
.merge(self $toBeMerged): self
Returns new instance with data-set combined from parent and$toBeMerged
instances. Both source instances stay unchanged.deduct(self $toBeDeducted): self
Returns new instance with data-set containing all items from parent that are not contained in$toBeDeducted
. Both source instances stay unchanged.count(): int
Returns data-set size.isEmpty(): bool
Returnstrue
if data-set is empty,false
otherwise.
Array-types-specific extractors:
static extractOrEmpty(array $data, string $key): self
Behaves like standard::extract()
method, but returns empty set when$data[$key]
isnull
or not set.static extractNotEmpty(array $data, string $key): self
Behaves like standard::extract()
method, but throwsInvalidTypeException
when$data[$key]
is not set,null
or empty array.
UniqueIntArray
SmartEmailing\Types\UniqueIntArray
UniqueIntArray is able to hold unique set of integers.
Can be created from:
// duplicate values will be discarted
// keys are ignored
UniqueIntArray::from(
[
1, 2, 2, 3, 3, 3, 4
]
);
Type-specific methods:
getValues(): int[]
Returns data-set of unique integers as array.toArray(): int[]
Is just alias forgetValues()
.add(int $id): bool
Adds another integer to the data-set. Returnsfalse
if integer has already been there.remove(int $id): void
Removes integer from the data-set, if present.contains(int $id): bool
Returnstrue
if$id
is contained in the data-set,false
otherwise.
UniqueStringArray
SmartEmailing\Types\UniqueIntArray
UniqueStringArray is able to hold unique set of strings.
Can be created from:
// duplicate values will be discarted
// keys are ignored
UniqueStringArray::from(
[
'a',
'b',
'c',
'all work and no play makes jack a dull boy',
'all work and no play makes jack a dull boy',
'all work and no play makes jack a dull boy',
]
);
Type-specific methods:
getValues(): string[]
Returns data-set of unique strings as array.toArray(): string[]
Is just alias forgetValues()
.add(string $id): bool
Adds another string to the data-set. Returnsfalse
if string has already been there.remove(string $id): void
Removes string from the data-set, if present.contains(string $id): bool
Returnstrue
if$id
is contained in the set,false
otherwise.
Enum-extractable types
Enum-extractable types are types that can contain single value from defined set. They are based on kkk
All Enum-extractable types share following features:
getValue() : string
Returns enum-valueequals(self $enum): bool
Returnstrue
if$enum
contains same value as parent.equalsValue(string $value): self
Returnstrue
if parent contains the same value as$value
.
Enums can be created using standard extractors or using their constants:
CurrencyCode::from(
CurrencyCode::EUR
);
CurrencyCode::from(
'EUR'
);
Lawful Basis For Processing
SmartEmailing\Types\LawfulBasisForProcessing
GDPR's lawful basis for processing
Country code
SmartEmailing\Types\CountryCode
ISO-3166-1 Alpha 2 country code
Currency code
SmartEmailing\Types\CurrencyCode
ISO-4217 three-letter currency code
Field of Application
SmartEmailing\Types\FieldOfApplication
Most common fields of human applications.
Time unit
SmartEmailing\Types\TimeUnit
Time unit compatible with \DateTime::modify()
argument format
Relation
SmartEmailing\Types\Relation
Represents Relation or Gate - AND / OR