SmartEmailing \ Types
Missing data types for PHP 8.1 and greater. Highly extendable, production tested.
, (*1)
, (*2)
Neverending data validation can be exhausting. 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 problems., (*3)
Smelly, right?, (*4)
Replacing validation hell with Types will make
your code much more readable and less vulnerable to bugs., (*5)
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., (*6)
, (*7)
Table of Contents
Installation
The recommended way to install is via Composer:, (*8)
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., (*9)
Types consist from:, (*10)
- 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:, (*11)
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
This is really useful for strict-typing (validation) multidimensional arrays like API requests, forms or database data., (*12)
<?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 are based on validated strings. All values are trimmed before validation., (*13)
They can be easily converted back to string by string-type casting or calling $type->getValue()
., (*14)
E-mail address
SmartEmailing\Types\Emailaddress
, (*15)
Lowercased and ASCII-transformed e-mail address (hello@gmail.com
), (*16)
Type-specific methods:
- getLocalPart() : string
returns local part of e-mail address (hello
)
- getDomain() : \SmartEmailing\Types\Domain
returns domain part (gmail.com
, represented as Types\Domain
), (*17)
Non-empty string
SmartEmailing\Types\NonEmptyString
, (*18)
Trimmed non-empty string., (*19)
Domain
SmartEmailing\Types\Domain
, (*20)
Lowercased domain name (mx1.googlemx.google.com
), (*21)
Type-specific methods:
- getSecondLevelDomain() : \SmartEmailing\Types\Domain
returns second-level domain. (google.com
), (*22)
Hex 32
SmartEmailing\Types\Hex32
, (*23)
Lowercased 32-characters long hexadecimal string useful as container for MD5 or UUID without dashes. (741ecf779c9244358e6b85975bd13452
), (*24)
Hex color
SmartEmailing\Types\HexColor
, (*25)
Uppercased 7-characters long string useful as container for color. (#006EDB
), (*26)
GUID
SmartEmailing\Types\Guid
, (*27)
Lowercased Guid with dashes (741ecf77-9c92-4435-8e6b-85975bd13452
), (*28)
IP address
SmartEmailing\Types\IpAddress
, (*29)
IP address v4 or v6. (127.0.0.1
, [2001:0db8:0a0b:12f0:0000:0000:0000:0001]
, 2001:db8:a0b:12f0::1
), (*30)
Type-specific methods:
- getVersion() : int
returns IP address version, 4
or 6
, (*31)
URL
SmartEmailing\Types\UrlType
, (*32)
URL based on Nette\Http\Url
(https://www.google.com/search?q=all+work+and+no+play+makes+jack+a+dull+boy
), (*33)
- all spaces in string are urlencoded
- all non-ascii characters are urlencoded
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 as string
, alias for getValue()
- 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
Returns true
if URL parameters contain all parameters defined in $names
array
- getParameters(): array
Returns all URL parameters as string-indexed array
- withQueryParameter(string $name, mixed $value): UrlType
Returns new instance with added query parameter., (*34)
Company registration number
SmartEmailing\Types\CompanyRegistrationNumber
, (*35)
Whitespace-free company registration number for following countries:
CZ
, SK
, CY
, (*36)
Phone number
SmartEmailing\Types\PhoneNumber
, (*37)
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
, (*38)
Type-specific methods:
- getCountry() : SmartEmailing\Types\CountryCode
Originating country (CZ
), (*39)
ZIP code
SmartEmailing\Types\ZipCode
, (*40)
Whitespace-free ZIP code valid in following countries:
CZ
, SK
, UK
, US
, (*41)
JSON
SmartEmailing\Types\JsonString
, (*42)
Valid JSON-encoded data as string, (*43)
Type-specific methods:
- static from(mixed $data) : SmartEmailing\Types\JsonString
Accepts string or array. Crates JsonString from valid json string or raw data (array)
- static encode(mixed $data) : SmartEmailing\Types\JsonString
create JsonString from raw data (array)
- getDecodedValue() : mixed
decode JsonString back to raw data, (*44)
Base 64
SmartEmailing\Types\Base64String
, (*45)
Valid Base 64-encoded data as string, (*46)
Type-specific methods:
- static encode(string $value) : SmartEmailing\Types\Base64String
create Base64String from string
- getDecodedValue() : string
decode Base64String back to original string, (*47)
Iban
SmartEmailing\Types\Iban
, (*48)
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\CountryCode
- getChecksum(): int
, (*49)
SwiftBic
SmartEmailing\Types\SwiftBic
, (*50)
Valid Swift/Bic codes., (*51)
VatId
SmartEmailing\Types\VatId
, (*52)
Type-specific methods:
- static isValid(string $vatId): bool
returns true if the vat id is valid otherwise returns false
- getCountry(): ?Country
returns Country
under which the subject should falls or null.
- getPrefix(): ?string
returns string that prefixing vat id like EL
from EL123456789
or null.
- getVatNumber(): string
returns vat number without prefix like 123456789
- getValue(): string
return whole vat id EL123456789
, (*53)
CurrencyCode
SmartEmailing\Types\CurrencyCode
, (*54)
Valid currency codes by ISO 4217, (*55)
CountryCode
SmartEmailing\Types\CountryCode
, (*56)
Valid country codes by ISO 3166-1 alpha-2, (*57)
Int-extractable types are based on validated integers., (*58)
They can be easily converted back to int by int-type casting or calling $type->getValue()
., (*59)
Port
SmartEmailing\Types\Port
, (*60)
Port number, (*61)
Integer interval, <0, 65535>
, (*62)
Quantity
SmartEmailing\Types\Quantity
, (*63)
Quantity of items, (*64)
Integer interval, <1, PHP_INT_MAX>
, (*65)
Unsigned Integer
SmartEmailing\Types\UnsignedInt
, (*66)
Usigned integer, (*67)
Integer interval, <0, PHP_INT_MAX>
, (*68)
Float-extractable types are based on validated floats., (*69)
They can be easily converted back to float by float-type casting or calling $type->getValue()
., (*70)
Part
SmartEmailing\Types\Part
, (*71)
Portion of the whole, (*72)
Float interval <0.0, 1.0>
, (*73)
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, (*74)
Sigmoid function value
SmartEmailing\Types\SigmoidValue
, (*75)
Result of Sigmoid function, useful when building neural networks., (*76)
Float interval <-1.0, 1.0>
., (*77)
Rectified Linear Unit function value
SmartEmailing\Types\ReLUValue
, (*78)
Result of Rectified Linear Unit function, useful when building neural networks., (*79)
Float interval <0.0, Infinity)
., (*80)
Unsigned Float
SmartEmailing\Types\UnsignedFloat
, (*81)
Usigned float, (*82)
Float interval, <0, PHP_FLOAT_MAX>
, (*83)
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., (*84)
DateTimeRange
SmartEmailing\Types\DateTimeRange
, (*85)
Range between two \DateTimeInterface
s. Safe for datetimes out of range of unix timestamp., (*86)
Can be created from:, (*87)
DateTimeRange::from(
[
'from' => 'YYYY-MM-DD HH:MM:SS',
'to' => 'YYYY-MM-DD HH:MM:SS',
]
)
Type-specific methods:
- getFrom(): \DateTimeImmutable
returns From
date and time as \DateTimeImmutable
instance
- getTo(): \DateTimeImmutable
returns To
date and time as \DateTimeImmutable
instance
- getDurationInSeconds(): int
returns number of seconds between From
and To
dates
- contains(\DateTimeInterface $dateTime): bool
returns true
if provided \DateTimeInterface
lies between From
and To
dates.
- getLengthInSeconds(): int
returns duration length in seconds, (*88)
Duration
SmartEmailing\Types\Duration
, (*89)
Human-readable time interval., (*90)
Can be created from:, (*91)
Duration::from(
[
'value' => 1,
'unit' => TimeUnit::HOURS,
]
);
Duration::from(
'1 hours'
);
Type-specific methods:
- getDateTimeModify(): string
returns string that is compatible with \DateTime::modify()
and \DateTimeImmutable::modify()
- getUnit(): TimeUnit
returns TimeUnit
enum type
- getValue() int
returns number of units
- static fromDateTimeModify(string $dateTimeModify): self
creates new instance from string compatible with \DateTime::modify()
and \DateTimeImmutable::modify()
, (*92)
Address
SmartEmailing\Types\Address
, (*93)
Location address contains street and number, town, zip code and country., (*94)
Can be created from:, (*95)
Address::from(
[
'street_and_number' => '29 Neibolt Street',
'town' => 'Derry',
'zip_code' => '03038',
'country' => 'US',
]
);
Type-specific methods:
- getStreetAndNumber(): string
returns street and number
- getTown(): string
returns Town
- getZipCode(): ZipCode
returns ZipCode instance
- getCountry(): CountryCode
returns CountryCode instance, (*96)
Price
SmartEmailing\Types\Price
, (*97)
Price object containing number of currency units with VAT, number of currency units without VAT and currency., (*98)
Can be created from:, (*99)
Price::from(
[
'with_vat' => 432.1,
'without_vat' => 123.45,
'currency' => CurrencyCode::EUR,
]
);
Type-specific methods:
- getWithoutVat(): float
returns price without VAT
- getWithVat(): float
returns price with VAT
- getCurrency(): CurrencyCode
returns CurrencyCode instance, (*100)
Login credentials
SmartEmailing\Types\LoginCredentials
, (*101)
Value object containing login and plain password.
You should use it just in-memory in authentication process and than drop it., (*102)
Can be created from:, (*103)
LoginCredentials::from(
[
'login' => 'admin',
'password' => 'BLzW75kJxEa7YXuqF9Di',
]
);
Type-specific methods:
- getLogin(): string
returns login
- getPassword(): string
returns password, (*104)
Key-Value pair
SmartEmailing\Types\KeyValue
, (*105)
Value object containing string key and string value., (*106)
Can be created from:, (*107)
KeyValuePair::from(
[
'key' => 'overlook',
'value' => 'all_work_and_no_play_makes_jack_a_dull_boy',
]
);
Type-specific methods:
- getKey(): string
returns key
- getValue(): string
returns value, (*108)
Scalar leaves array
SmartEmailing\Types\ScalarLeavesArray
, (*109)
Value object containing single or multi-dimensional array with only scalar or NULL values in it's leaves. Array keys stay untouched., (*110)
Can be created from:, (*111)
ScalarLeavesArray::from(
[
[
'a',
],
[
1,
],
[
'b',
[
true,
[
null,
],
[],
],
],
]
);
Array-types-specific extractors:
- static extractOrEmpty(array $data, string $key): self
Behaves like standard ::extract()
method, but returns empty ScalarLeavesArray when $data[$key]
is null
or not set., (*112)
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., (*113)
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
Returns true
if data-set is empty, false
otherwise., (*114)
Array-types-specific extractors:
- static extractOrEmpty(array $data, string $key): self
Behaves like standard ::extract()
method, but returns empty set when $data[$key]
is null
or not set.
- static extractNotEmpty(array $data, string $key): self
Behaves like standard ::extract()
method, but throws InvalidTypeException
when $data[$key]
is not set, null
or empty array., (*115)
UniqueIntArray
SmartEmailing\Types\UniqueIntArray
, (*116)
UniqueIntArray is able to hold unique set of integers., (*117)
Can be created from:, (*118)
// 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 for getValues()
.
- add(int $id): bool
Adds another integer to the data-set. Returns false
if integer has already been there.
- remove(int $id): void
Removes integer from the data-set, if present.
- contains(int $id): bool
Returns true
if $id
is contained in the data-set, false
otherwise., (*119)
UniqueStringArray
SmartEmailing\Types\UniqueIntArray
, (*120)
UniqueStringArray is able to hold unique set of strings., (*121)
Can be created from:, (*122)
// 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 for getValues()
.
- add(string $id): bool
Adds another string to the data-set. Returns false
if string has already been there.
- remove(string $id): void
Removes string from the data-set, if present.
- contains(string $id): bool
Returns true
if $id
is contained in the set, false
otherwise., (*123)
Enum-extractable types are types that can contain single value from defined set. They are based on kkk, (*124)
All Enum-extractable types share following features:
- getValue() : string
Returns enum-value
- equals(self $enum): bool
Returns true
if $enum
contains same value as parent.
- equalsValue(string $value): self
Returns true
if parent contains the same value as $value
., (*125)
Enums can be created using standard extractors or using their constants:, (*126)
CurrencyCode::from(
CurrencyCode::EUR
);
CurrencyCode::from(
'EUR'
);
Lawful Basis For Processing
SmartEmailing\Types\LawfulBasisForProcessing
, (*127)
GDPR's lawful basis for processing, (*128)
Available values, (*129)
Country code
SmartEmailing\Types\CountryCode
, (*130)
ISO-3166-1 Alpha 2 country code, (*131)
Available values, (*132)
Currency code
SmartEmailing\Types\CurrencyCode
, (*133)
ISO-4217 three-letter currency code, (*134)
Available values, (*135)
Field of Application
SmartEmailing\Types\FieldOfApplication
, (*136)
Most common fields of human applications., (*137)
Available values, (*138)
Time unit
SmartEmailing\Types\TimeUnit
, (*139)
Time unit compatible with \DateTime::modify()
argument format, (*140)
Available values, (*141)
Relation
SmartEmailing\Types\Relation
, (*142)
Represents Relation or Gate - AND / OR, (*143)
Available values, (*144)
Primitive types and Arrays
Types are able to get and extract primitives using IntType
, IntArray
, FloatType
, FloatArray
, StringType
, StringArray
, BoolType
, BoolArray
and Array
classes. See examples below:, (*145)
<?php
declare(strict_types = 1);
use SmartEmailing\Types\Arrays;
use SmartEmailing\Types\BoolArray;
use SmartEmailing\Types\BoolType;
use SmartEmailing\Types\FloatArray;
use SmartEmailing\Types\FloatType;
use SmartEmailing\Types\IntArray;
use SmartEmailing\Types\IntType;
use SmartEmailing\Types\StringArray;
use SmartEmailing\Types\StringType;
use SmartEmailing\Types\InvalidTypeException;
IntType::from(666); // 666
IntType::from('666'); // 666
IntType::from(666.1); // throws InvalidTypeException
IntType::from('abcd'); // throws InvalidTypeException
IntType::from('abcd'); // throws InvalidTypeException
IntType::fromOrNull(null); // null
IntType::fromOrNull(1); // 1
IntType::fromOrNull('abcd'); // throws InvalidTypeException
IntType::fromOrNull('abcd', true); // null
FloatType::from(1.1); // 1.1
FloatType::from('1.1'); // 1.1
FloatType::from(1); // 1.0
FloatType::from('1'); // 1.0
FloatType::from('xxx'); // throws InvalidTypeException
FloatType::fromOrNull(null); // null
FloatType::fromOrNull(1.0); // 1.0
FloatType::fromOrNull('abcd'); // throws InvalidTypeException
FloatType::fromOrNull('abcd', true); // null
StringType::from('xxx'); // 'xxx'
StringType::from(5); // '5'
StringType::from(5.0); // '5'
StringType::from(5.1); // '5.1'
StringType::fromOrNull(null); // null
StringType::fromOrNull('abcd'); // 'abcd'
StringType::fromOrNull([]); // throws InvalidTypeException
StringType::fromOrNull([], true); // null
BoolType::from(true); // true
BoolType::from(false); // false
BoolType::from(1); // true
BoolType::from(0); // false
BoolType::from('1'); // true
BoolType::from('0'); // false
BoolType::from('true'); // true
BoolType::from('false'); // false
Arrays::from([1, 2]); // [1, 2]
Arrays::from([1, 'abcd']); // [1, 'abcd']
IntArray::from([1, '2']); // [1, 2]
IntArray::fromOrNull([1, '2']); // returns int[]|null
FloatArray::from([1, '2']); // [1.0, 2.0]
FloatArray::fromOrNull([1, '2']); // returns float[]|null
StringArray::from([1, '2']); // ['1', '2']
StringArray::fromOrNull([1, '2']); // returns string[]|null
BoolArray::from([1, '1']); // [true, true]
BoolArray::fromOrNull([1, '1']); // returns bool[]|null
// All primitive types have their extract equivalent:
IntType::extract($data, 'key');
IntType::extractOrNull($data, 'key');
IntType::extractOrNull($data, 'key', true);
StringType::extract($data, 'key');
StringType::extractOrNull($data, 'key');
StringType::extractOrNull($data, 'key', true);
FloatType::extract($data, 'key');
FloatType::extractOrNull($data, 'key');
FloatType::extractOrNull($data, 'key', true);
Arrays::extract($data, 'key'); //returns mixed[]
Arrays::extractOrNull($data, 'key'); //returns mixed[]|null
IntArray::extract($data, 'key'); //returns int[]
IntArray::extractOrNull($data, 'key'); //returns int[]|null
FloatArray::extract($data, 'key'); //returns float[]
FloatArray::extractOrNull($data, 'key'); //returns float[]|null
StringArray::extract($data, 'key'); //returns string[]
StringArray::extractOrNull($data, 'key'); //returns string[]|null
BoolArray::extract($data, 'key'); //returns bool[]
BoolArray::extractOrNull($data, 'key'); //returns bool[]|null
DateTimes and DateTimesImmutable
Types are able to get and extract \DateTime
and \DateTimeImmutable
objects using DateTimes
and DateTimesImmutable
classes.
Supported format Y-m-d H:s:i
.
API is the same as for other types, so available methods are (shown for DateTimes
):, (*146)
from(string $dateTime ) : \DateTime
extract(array $data, string $index) : \DateTime
extractOrNull(array $data, string $index, bool $getNullIfInvalid) : ?\DateTime
Dates and DatesImmutable
Types are able to get and extract \DateTime
and \DateTimeImmutable
objects using Dates
and DatesImmutable
classes. Dates are created with time sets on 00:00:00
.
Supported format Y-m-d
.
API is the same as for other types, so available methods are (shown for Dates
):, (*147)
from(string $dateTime ) : \DateTime
extract(array $data, string $index) : \DateTime
extractOrNull(array $data, string $index, bool $getNullIfInvalid) : ?\DateTime
Writing your own types
Implementing your custom type is easy!
At first you have to decide what extractable-type should your new custom type be and
use
particular extractable-trait in it's class to enhance it by all extractable features.
The only thing you have to do next is implement class construtor and throw InvalidTypeException in case of invalid data.
You can see examples for every extractable-type below., (*148)
One more thought - if you think your new type will be useful for others, please, contribute!, (*149)
How to contribute
Thank you for your interest in improving Types!️ ❤️ 🖖, (*150)
Before you open pull request, please, make sure you
did not forget to write tests for your code., (*151)
Then run following commands:, (*152)
1) vendor/bin/tester tests
Run tests locally. It takes just two seconds :-), (*153)
2) bin/cbf
This will check the code and automatically fix some code style issues
like indentation or line breaks., (*154)
3) bin/cs
This will run another code style check that will notify you about
problems that must be fixed manually.
Please, fix them, and re-run the command., (*155)
4) bin/stan
PHP Static analysis tool - this will check the code for some
smelly constructions that should be refactored.
Please, fix them, and re-run the command., (*156)
5) PR ready!, (*157)
We are hiring
Do you like our code? If you want to be part of SmartEmailing, we are hiring., (*158)