Download the PHP package firemidge/value-objects without Composer
On this page you can find all versions of the php package firemidge/value-objects. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download firemidge/value-objects
More information about firemidge/value-objects
Files in firemidge/value-objects
Package value-objects
Short Description Convenience methods for working with value objects
License GPL-3.0-or-later
Informations about the package value-objects
value-objects
Tested with PHP 8.4. Requires PHP ^8.1.
This library provides convenience methods for creating value objects in the form of traits, as well as some generic classes implementing said traits to use as-is where no configuration is needed.
You may use the below table to decide which type is best for you. "Single Value" means the object will hold a single value, whereas "Array of Values" means the object can hold more than one value.
You can click on the relevant type to jump straight to their documentation.
Single Value | Array of Values | |
---|---|---|
List of Valid Values | IsIntStringMapType |
IsArrayEnumType |
Any Value/Custom Validation | IsIntType |
IsCollectionType |
Generic classes
They only exist for convenience, already implementing a type trait with no or minimal configuration. All classes are extendable if needed, or you can implement the relevant trait directly.
Name | Implemented trait | Notes |
---|---|---|
AnyCollection |
IsCollectionTrait |
Used when you just want to access an array using normalised OOP methods rather than PHP-native global functions, while not caring about the type of elements. |
AnyFloat |
IsFloatType |
Used when you do not want to customise min/max value or other validation rules and the value is a float. |
AnyInteger |
IsIntType |
Used when you do not want to customise min/max value or other validation rules and the value is an integer. |
AnyString |
IsStringType |
Used when there are no rules about the format of the string and there is no list of valid values either. |
Email |
IsEmailType |
Used when dealing with an email address without custom validation rules/custom formatting. |
Percentage |
IsFloatType |
Used when expecting a value between 0 and 100, which can be represented as a string (with a % symbol), an integer, or a float (with a customisable number of decimal places. Passing a value less than 0 or greater than 100 results in an exception (rather than being clipped silently. The class can be extended to configure further. |
Quality Control
The following table is updated with each code update and is generated with the help of PhpUnit (unit testing tool) and Infection (mutation testing tool):
Percentage | Description | |
---|---|---|
Code Coverage | How many methods have been fully covered by tests. | |
Mutation Score Indicator | Indicates how many generated mutants were detected. Note that some mutants are false positives. | |
Mutation Code Coverage | Should be in the same ballpark as the normal code coverage. Formula: (TotalMutantsCount - NotCoveredByTestsCount) / TotalMutantsCount |
|
Covered Code MSI | This is the MSI (Mutation Score Indicator) for code that is actually covered by tests. It shows how effective the tests really are. Formula: TotalDefeatedMutants / (TotalMutantsCount - NotCoveredByTestsCount) . |
IsStringEnumType
Use this type when there is a set of fixed valid values, and your object represents a single value.
If there is a set of fixed valid values but your object represents an array of values, use IsStringArrayEnumType
.
If you do not need to do any configuration, there is a generic class available, implementing this type: FireMidge\ValueObject\Generic\AnyString
.
Example:
Usage:
IsIntEnumType
Use this type when there is a set of fixed valid values, and your object represents a single value.
If there is a set of fixed valid values but your object represents an array of values, use IsIntArrayEnumType
.
Example:
Usage:
IsEmailType
Use this type when the value represents a single e-mail address.
This trait uses IsStringType
under the hood but performs standard e-mail validation.
If you do not need to do any configuration, there is a generic class available, implementing this type: FireMidge\ValueObject\Generic\Email
.
Example:
Usage:
IsStringType
Use this type when the value represents a single string value, but there is no fixed set of valid values.
If you are expecting an e-mail address, you can use the IsEmailType
trait instead, which will perform format validation checks.
Validation
To provide custom validation, override protected function validate(string $value) : void
.
If you want to only validate the length of the string, you can call validateLength(string $value, ?int $minLength = null, ?int $maxLength = null) : void
inside the validate
method.
String transformation
If you want to transform the input value but not fail validation, override protected function transform(string $value) : string
.
There are 3 convenience methods available that you can call inside transform
if you want:
trimAndLowerCase(string $value)
trimAndUpperCase(string $value)
trimAndCapitalise(string $value)
Example:
Usage:
IsIntType
Use this type when the value represents a single integer value, but there is no fixed list of valid values, or it is not feasible to write up each valid value.
If you do not need to do any configuration, there is a generic class available, implementing this type: FireMidge\ValueObject\Generic\AnyInteger
.
Validation
You can provide custom validation rules by overriding protected function validate(int $value) : void
. By default, it will validate that the value is a positive integer.
If you only want to validate that a value is between a certain minimum and maximum value, override protected static function minValidValue() : ?int
and protected static function maxValidValue() : ?int
. Returning NULL
from either means there is no limitation to the minimum or the maximum value respectively.
Example:
Note that there is a convenient Percentage
class already available: FireMidge\ValueObject\Generic\Percentage
.
Another example, for a value without any limitations:
Another example, for a value which has no upper limit but may never be below 5.
Another example which only allows odd values:
Usage:
IsFloatType
Use this type when the value represents a single float value.
If you do not need to do any configuration, there is a generic class available, implementing this type: FireMidge\ValueObject\Generic\AnyFloat
.
Validation
You can provide custom validation rules by overriding protected function validate(float $value) : void
. By default, it will only validate the float is above 0, but you can change this to allow unlimited values by overriding minValidValue
.
If you only want to validate that a value is between a certain minimum and maximum value, override protected static function minValidValue() : ?float
and protected static function maxValidValue() : ?float
. Returning NULL
from either means there is no limitation to the minimum or the maximum value respectively.
Example, which allows a value between 0 and 100, and which automatically crops any decimal points after the 3rd:
Usage:
IsIntStringMapType
Use this type if the value represents a single value which can be mapped between an integer and a string.
This may be useful when you e.g. store a value in the database as an integer (for faster indexing), but convert it to a string for a public API (for better readability).
Example:
Usage:
IsIntArrayEnumType
Use this type when the value represents an array of integer values, where each value must be one of a fixed list of values.
Useful when e.g. building filters, allowing to select a number of statuses or IDs (or others) to be included in the result.
Unique values
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Example:
Usage:
IsStringArrayEnumType
Use this type when the value represents an array of string values, where each value must be one of a fixed list of values.
Useful when e.g. building filters, allowing to select a number of fields in the result.
Unique values
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Example:
Usage:
IsClassArrayEnumType
Use this type when the value represents an array of class instances, and there is a list of valid values. This means the class instances represent enum types.
Example:
It is very similar to using IsIntArrayEnumType
with the exception that each item in this array type is a class instance. It means individual items can be added without having to be converted into a scalar type, as in the usage example below:
Usage:
Because classes implementing IsClassArrayEnumType
hold objects, you can perform method calls on returned elements, as in the example below:
Usage:
Unique values
By default, the same value can be added multiple times to the same instance. To control this behaviour, see the example below:
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Note: In order to perform these duplicate checks, the value object is converted into a string first. Make sure you have the __toString
method implemented if you use custom classes and want these checks. (If you're using any of the types within this library, __toString
is already implemented on them.)
Validation
By default, each element is already being validated for being an object, and an instance of the particular class returned by className()
. However, if you want additional validation to be performed, you can override protected function validateEach(mixed $value) : void
, which is executed for each value separately, both when instantiating it and when calling withValue
. Note that this validation will also run before withoutValue
, tryWithoutValue
and contains
, so you are notified when passing something entirely invalid rather than it being silently swallowed. Make sure to also call parent::validateEach($value);
unless you want to repeat the default validation behaviour in your overridden version.
From raw values
If you want to instantiate your collection from "raw" values (as opposed to instances of a class) for convenience reasons (whilst internally converting them to the relevant instances), you can use fromRawValues
.
Example:
This works for a conversion to instances that implement fromString
, fromInt
, fromBool
, fromFloat
, fromDouble
, fromNumber
or accept the relevant parameter through their constructor. Note that input types are NOT converted. That means if you pass a string
, only the fromString
factory method will be attempted.
If none of the above are present or succeed, the trait will attempt to pass the value into the constructor of the target class. (Should this fail as well, a ConversionError
is thrown.)
Custom conversion
If you would like to use the fromRawValues
method but your target class has neither of the before-mentioned methods or ways of instantiating, you have three options:
1) Provide a custom callback
If you only need to do a custom conversion once, you can provide a callback to the fromRawValues
method directly.
Example:
2) Override convertFromRaw
If you use a custom conversion more than once on the class, you have the option of overriding protected static function convertFromRaw(mixed $value) : object
to automatically use your custom converter every time fromRawValues
is called.
Example:
3) Implement your own factory method
Since everything is just a trait, you of course have the option of simply creating your own and replace fromRawValues
. If you want to keep the same name for your own method and change the signature, just alias the trait's method and make it private.
Usage:
IsArrayEnumType
Use this type when the value represents an array of values of a type other than string
, integer
or an instance of a specific class (for those we have IsClassArrayEnumType
respectively) and where there is a list of valid values.
Combination with other types
You can combine this type with any other type, e.g. to get an array of float types, or an array of int enum types, etc. The difference to using a combination of IsClassArrayEnumType
for more information.
Unique values
By default, the same value can be added multiple times to the same instance. To control this behaviour, see the example below:
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Note: In order to perform these duplicate checks, the value object is converted into a string first. Make sure you have the __toString
method implemented if you use custom classes and want these checks. (If you're using any of the types within this library, __toString
is already implemented on them.)
Validation
You can provide custom validation by overriding protected function validateEach(mixed $value) : void
, which is executed for each value separately, both when instantiating it and when calling withValue
. Note that this validation will also run before withoutValue
, tryWithoutValue
and contains
, so you are notified when passing something entirely invalid rather than it being silently swallowed.
Example:
Note that the example above is for demonstration purpose only - all of the above functionality comes out of the box by using IsClassArrayEnumType
.
Usage:
You also have a variety of other array methods available, e.g.:
IsClassCollectionType
Use this type when the value represents an array of values, where each value must be an instance of a class and there is no finite list of valid values.
If there is a list of valid values, use IsArrayEnumType
.
If the values are not instances of a class, use IsCollectionType
.
Unique values
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Validation
You can provide custom validation by overriding protected function validateEach(mixed $value) : void
, which is executed for each value separately, both when instantiating it and when calling withValue
. Note that this validation will also run before withoutValue
, tryWithoutValue
and contains
, so you are notified when passing something entirely invalid rather than it being silently swallowed.
Example:
From raw values
If you want to instantiate your collection from "raw" values (as opposed to instances of a class) for convenience reasons (whilst internally converting them to the relevant instances), you can use fromRawValues
.
Example:
This works for a conversion to instances that implement fromString
, fromInt
, fromBool
, fromFloat
, fromDouble
, fromNumber
or accept the relevant parameter through their constructor. Note that input types are NOT converted. That means if you pass a string
, only the fromString
factory method will be attempted.
If none of the above are present or succeed, the trait will attempt to pass the value into the constructor of the target class. (Should this fail as well, a ConversionError
is thrown.)
Custom conversion
If you would like to use the fromRawValues
method but your target class has neither of the before-mentioned methods or ways of instantiating, you have three options:
1) Provide a custom callback
If you only need to do a custom conversion once, you can provide a callback to the fromRawValues
method directly.
Example:
2) Override convertFromRaw
If you use a custom conversion more than once on the class, you have the option of overriding protected static function convertFromRaw(mixed $value) : object
to automatically use your custom converter every time fromRawValues
is called.
Example:
3) Implement your own factory method
Since everything is just a trait, you of course have the option of simply creating your own and replace fromRawValues
. If you want to keep the same name for your own method and change the signature, just alias the trait's method and make it private.
Usage:
IsCollectionType
Use this type when the value represents an array of values and there is no finite list of valid values. If there is a list of valid values, use IsStringArrayEnumType
if applicable).
If you do not need to do any configuration, there is a generic class available, implementing this type: FireMidge\ValueObject\Generic\AnyCollection
.
Combination with other types
You can combine this type with any other type, e.g. to get an array of float types, an array of e-mail addresses, etc.
If you need each value to be an instance of a class, consider using IsClassCollectionType
instead.
Unique values
If each value can only appear once in the object, you have two options:
- If you want an exception to be thrown when duplicate values are being added (either via
fromArray
or viawithValue
), then overrideprotected static function areValuesUnique() : bool
and returntrue
. An exception of typeDuplicateValue
will be thrown. - If you do not want an exception to be thrown but want duplicate values to simply be silently ignored (both in
fromArray
and inwithValue
), overrideprotected static function ignoreDuplicateValues() : bool
and returntrue
. If duplicate values are found, they are only added once to the array.
When both areValuesUnique
and ignoreDuplicateValues
return true
, ignoreDuplicateValues
takes precedence.
Validation
You can provide custom validation by overriding protected function validateEach(mixed $value) : void
, which is executed for each value separately, both when instantiating it and when calling withValue
. Note that this validation will also run before withoutValue
, tryWithoutValue
and contains
, so you are notified when passing something entirely invalid rather than it being silently swallowed.
It is recommended to set up validation, at least for the value type.
Value transformation
If you want to transform the input value but not fail validation, override protected function transformEach(mixed $value)
.
By also using the trait CanTransformStrings
, you'll get 3 convenience methods that you can call inside transform
if you want:
trimAndLowerCase(string $value)
trimAndUpperCase(string $value)
trimAndCapitalise(string $value)
Example:
Usage:
All versions of value-objects with dependencies
ext-mbstring Version *