Releases: ReallifeKip/ImmutableBase
Releases · ReallifeKip/ImmutableBase
v4.3.0
Added
#[InputKeyTo(KeyCase::X)]— Input key case conversion. Apply at class level to remap all incoming array keys before hydration, or at property level to override for a specific property. Conversion splits on camelCase/PascalCase boundaries, underscores, hyphens, and whitespace, then rejoins in the target case.#[OutputKeyTo(KeyCase::X)]— Output key case conversion. Apply at class level to remap all serialized keys duringtoArray(true)/toJson(true), or at property level to override for a specific property.KeyCaseenum — 8 naming conventions:Snake(nick_name),PascalSnake(Nick_Name),Macro(NICK_NAME),Camel(nickName),Pascal(NickName),Kebab(nick-name),CamelKebab(nick-Name),Train(Nick-Name).InvalidKeyCaseException— Thrown at definition time when#[InputKeyTo]or#[OutputKeyTo]receives a value that is not aKeyCaseenum instance (e.g. a plain string).
v4.2.2
Fixed
- Mark
DataTransferObject::__constructasfinalto prevent
unintended override in subclasses, aligning implementation with
original design intent - Fix
@descannotation handling in ib-writer Markdown mode output:
replacedisset()check with strict empty string comparison,
preventing blank description lines from being written
v4.2.1
Refactored
- Internal Structure Optimization: Extracted typescript namespace rendering logic into a standalone renderNamespaces (formerly namespacesHandler) method to reduce cognitive complexity in contentGenerate.
- Naming Alignment: Renamed internal methods to strictly follow the render* naming convention for better clarity and maintainability.
- Control Flow Refactoring: Replaced several if-else blocks with match expressions to reduce Cyclomatic Complexity and align with Sonar quality standards.
Fixed
- Sonar Compliance: Added explicit documentation and justifications for empty methods to resolve "Methods should not be empty" code smells.
v4.2.0
Added
Nativeenum — Primitive typed arrays via#[ArrayOf].#[ArrayOf]now acceptsNative::string,Native::int,Native::float, andNative::boolto declare arrays of validated PHP scalar values without wrapping them in a SingleValueObject.ib-writerTypeScript output.vendor/bin/ib-writernow supports.tsgeneration, producingdeclare namespaceblocks with interfaces for DTO/VO, type aliases for SVO, and enum/union types for referenced PHP enums.
Changed
- Standalone
nullproperty type is now forbidden. Declaring a property typed asnullalone throwsInvalidPropertyTypeExceptionat scan time. Use?TypeorType|nullfor nullable properties. InvalidPropertyTypeExceptionmessage updated. Now explicitly lists allowed types and provides nullable usage guidance.InvalidArrayOfItemExceptionmessage updated. Now distinguishes between ImmutableBase class resolution failures and primitive type mismatches.
v4.1.2
Updated
- Update the composer description and keywords
v4.1.1
Fixed
ib-writer
- Property tables now include a
defaultcolumn displaying default
values from#[Defaults]attributes anddefaultValues()overrides - Enum types referenced as property types now generate their own
documentation blocks with case listings and backing values - BackedEnum defaults display the backing value; UnitEnum defaults
display the case name; dynamic defaults fromdefaultValues()
display as(dynamic)
v4.1.0
Added
defaultValues()— Static default value declaration. OverridedefaultValues(): arrayto declare fallback values for properties absent from input data. Keys must match declared property names; unmatched keys are silently ignored. Supports any type valid for the target property, including subclasses of ImmutableBase and Enum.#[Defaults(value)]— Attribute-based default value. Apply#[Defaults(value)]to individual properties for constant-expression defaults. Constrained by PHP attribute syntax to scalar values, arrays, and class constants.- Default value resolution priority. During construction (
fromArray/fromJson), property values are resolved in the following order:- Explicit input value (including explicit
null) defaultValues()[$propertyName]#[Defaults(value)]attribute valuenull(if nullable) orRequiredValueException
- Explicit input value (including explicit
- Explicit
nullis respected. When a key is present in the input with anullvalue, it is treated as an intentional assignment — default values are not applied. - Cache-aware default values.
ib-cacherserializes cacheable default values (scalars, arrays) into the cache file. Non-serializable defaults (objects, Closures) are excluded from the cache with a[Notice]warning and resolved at runtime viadefaultValues()on every construction. - SVO
defaultValues()sealed.SingleValueObject::defaultValues()is declaredfinaland returns an empty array. SVOs require explicit values viafrom()by design.
Changed
__construct()usesarray_key_exists()for default resolution. Replacesisset()to correctly distinguish between "key absent" (apply default) and "key present withnull" (respect explicit null).
v4.0.0
The first stable release of v4 — a complete architectural overhaul from attribute-based annotations to inheritance-based object definitions.
Highlights:
extends DataTransferObject / ValueObject / SingleValueObjectreplaces#[DataTransferObject]/#[ValueObject]- New
SingleValueObjecttype with TypeScript-like type narrowing - Automatic validation chain across inheritance hierarchy
with()deep path mutation with 44–68% performance improvement- CLI tools:
ib-cacher(metadata cache) +ib-writer(doc generation) - Zero dependencies. Requires PHP 8.4+.
📦 composer require reallifekip/immutable-base
Breaking Changes
- Architecture: Attribute annotation replaced by class inheritance. Objects are now defined by extending
DataTransferObject,ValueObject, orSingleValueObjectinstead of annotating with#[DataTransferObject],#[ValueObject], or#[Entity]. - Entity removed. The
Entityobject type has been removed entirely. - All properties must be
public. In v3,ValueObjectandEntityproperties wereprivatewith getter methods. All properties now requirepublicvisibility, enforced at scan time. Classes should be declared asreadonly class, which handles immutability at the PHP level. - Exception system rebuilt. All v3 exceptions have been removed and replaced with a structured hierarchy under
ImmutableBaseException, categorized intoLogicException>DefinitionException(design errors) andRuntimeException>InitializationException(input type violations) /ValidationException(domain constraint violations). See README for details. object,iterable, and non-IB/non-Enum class types forbidden. Properties typed asobject,iterable, or unsupported classes (e.g.DateTime,Closure) now throwInvalidPropertyTypeExceptionat scan time.
Added
SingleValueObject(SVO). New object type for semantically meaningful single values. Providesfrom(),__toString(),__invoke(), andjsonSerialize(). Child classes can freely define the type of$valuevia interface + hooked property design.equals(). Deep structural equality comparison for all ImmutableBase subclasses, with recursive comparison of nested objects and arrays.#[Strict]/#[Lax]. Control whether undeclared input keys are rejected or accepted.#[SkipOnNull]/#[KeepOnNull]. Control whether null-valued properties appear intoArray()/toJson()output.#[Spec]. Attach a domain-specific validation message to VO/SVO, retrievable viaValidationChainException::getSpec().#[ValidateFromSelf]. Reverse the validation chain direction to bottom-up (default is top-down).- Automatic validation chain. VO and SVO automatically traverse the entire inheritance hierarchy during construction. Each class in the chain is invoked if it defines
validate(): bool, but defining it is optional -- classes without it are simply skipped without breaking the chain. - Hierarchical error path tracing. Nested construction errors include the full property path in the exception message (e.g.
OrderDTO > $customer > $email > {error message}). ImmutableBase::strict(). Global strict mode.ImmutableBase::debug(). Debug logging for redundant input keys.ImmutableBase::loadCache(). Load pre-generated metadata cache to bypass runtime reflection.- CLI:
ib-cacher. Metadata cache generator. Supports--scan-dirfor targeted scanning and--clearfor cache removal. - CLI:
ib-writer. Documentation generator producing Mermaid class diagrams and Markdown property tables. - Benchmark suite. Dedicated benchmarks for
with()and hydration covering flat scalar updates, dot-notation deep paths, bracket notation, chained calls, and batch operations.
Changed
with()selective resolution. Only changed properties are resolved; unchanged properties are carried over by reference, yielding a 44–68% performance improvement depending on nesting depth.with()deep path syntax now supports bracket notation (items[0].sku) and custom separators, in addition to existing dot notation.
Deprecated
#[DataTransferObject]attribute — useextends DataTransferObject.#[ValueObject]attribute — useextends ValueObject.#[Entity]attribute — removed entirely.
v3.1.3
- Refactored core logic in
src/ImmutableBase.phpto introduce static caching for reflection properties and modes, enhancing performance for repeated operations. - Optimized
walkProperties()method to cache property lists per class, significantly reducing reflection overhead on subsequent calls. - Enhanced property initialization by extracting logic into dedicated
analyzeClass()method for better code organization and maintainability. - Improved
toArray()implementation with newanalyzeClassForToArray()callback method, providing cleaner separation of concerns. - Updated enum resolution with dedicated
analyzeEnum()method, improving readability and error handling for enum value assignments. - Enhanced PHPDoc documentation and method descriptions throughout
ImmutableBase.phpfor better developer experience and API clarity.
v3.1.2
- Fixed a bug where Immutable Objects implementing a custom constructor skipped the normal initialization flow, causing toArray() to consistently throw errors. The initialization step is now guaranteed before property traversal, ensuring toArray() works correctly even with custom constructors.