| schema | by dg | DOCS | | | |
| schema | by dg | removed support for key PreventMerging, removed Helpers::merge() (BC break) | | | |
| schema | by dg | AnyOf::merge() merges layers according to the matched alternative instead of blindly (BC break) | | | |
| schema | by dg | Structure::merge() driven by MergeMode; numeric-key appending decoupled from otherItems (BC break) | | | |
| schema | by dg | added MergeMode enum, mergeMode() and mergeWith(); arrays merge only according to the schema (BC break) Every element resolves its merging the same way: a mergeWith() closure (a pure combiner, legitimate for scalars too) wins outright, MergeMode::Replace returns the later layer wholesale, and arrays merge by keys with the mode deciding whether numeric elements append (AppendKeys, the default) or overwrite positionally (OverwriteKeys). Deep merging follows the schema only: ArrayType recurses through its items schema, and a colliding key holding arrays on both sides with no schema guidance is a CannotMerge error instead of a silent guess; an explicit mergeMode() is the declared opt-out. The blind Helpers::merge() no longer backs Type::mergeValues(); a null layer still loses to an array and beats a scalar. | | | |
| schema | by dg | ArrayType: mergeDefaults() are disabled by default (BC break) [Closes #28, Closes #31] | | | |
| schema | by dg | Schema::merge() receives Context and reports merge errors through it (BC break) | | | |
| schema | by dg | the options moved to the kind subclasses (BC break) min(), max(), pattern(), items() and mergeDefaults() live on NumberType, StringType and ArrayType; on a plain Type they throw DeprecatedException saying who has them, closing the deprecations 1.4 opened. Type::complete() became a template the subclasses hook into (coerce, validate, mergeDefault, normalizeValue, mergeValues), the items completion moved to ArrayType::completeItems() and describe() reports the subclass options tightened by a deprecated range in the expression. | | | |
| schema | by dg | Expect::type(): a union of different kinds is anyOf() (BC break) A union such as 'int|string' or 'scalar' has no options of its own (1.4 deprecated them), so Expect::type() now builds anyOf() of the variants via the new TypeExpression::format(), and error messages read "int|string" the way anyOf() reports alternatives. A union of a single kind ('int|float', 'int|null') keeps its subclass and its options, exactly as 1.4 promised. A directly constructed plain Type still accepts a union and keeps the 1.4 deprecation notice for its options. | | | |
| schema | by dg | Type validates by itself; Validators-coupled expressions are deprecated (BC break) Type checks the value against the parsed expression on its own: matches() is the one place that knows every Kind, and Validators is asked only about named string formats and the deprecated constructs. Those still work exactly as before but raise a notice and 2.1 refuses them: a range in the expression ('int:1..5', use min() and max()), a validator name that is not a type ('numeric' and friends, use assert()), and a directly constructed Type for a kind that has its own class (use Expect::type()). Helpers::validateType() and the deprecated helpers of Base are gone, getCastStrategy() no longer consults Validators for the builtin list. | | | |
| schema | by dg | used #Deprecated | | | |
| schema | by dg | Expect::from() works with class names | | | |
| schema | by dg | Expect::from() removed support for phpDoc annotations (BC break) | | | |
| schema | by dg | Schema: added return type hints (BC break) | | | |
| schema | by dg | opened 2.0-dev | | | |
| schema | by dg | updated DOCS | | | |
| schema | by dg | Expect::listOf() with wrap: a single value is accepted and wrapped into a one-item list | | | |
| schema | by dg | AnyOf: dynamic() is a flag, not a variant A DynamicParameter passes straight through instead of being matched against a Type(DynamicParameter::class) variant, which describe() would then have to recognize and hide. | | | |
| schema | by dg | added Expect::tuple() A tuple is a TupleType, a Structure with a list shape cast to an array whose layers replace each other wholesale - half-crossing two tuples is always nonsense, so merge() simply keeps the later layer. otherItems() naturally provides rest elements, describe() reports Kind::Tuple and JSON Schema exports prefixItems with the rest schema or false as items. Structure is no longer final. | | | |
| schema | by dg | added Expect::enum() for backed enums EnumType accepts a case or its backing value and yields the case; an enum-typed property of Expect::from() maps to it. The validation is still Type's instanceof, only a before() hook maps the backing value first, so messages and everything else stay the same. An enum class in Expect::type() keeps meaning plain instanceof, as for any other class; accepting values is what Expect::enum() is for. Expect::from() no longer recurses into an enum default as if it were a nested object. | | | |
| schema | by dg | added StringType, NumberType and ArrayType as kind-specific subclasses of Type Expect::string(), int(), listOf(), type('email') and the like return the subclass that says what kind of value it is; every instanceof Type, type hint and method called by name keeps working, Type is only no longer final. The subclasses add no behavior in 1.x: validation still goes through Validators, so Expect::type('url') and the other string pseudo-types keep working and are reported by describe() as strings in that format. Methods that make no sense for the kind (pattern() on a number or an array, items() outside arrays) are deprecated with a notice; the fluent setters return static. | | | |
| schema | by dg | added schema inspection (describe()) and JSON Schema export Type, Structure and AnyOf report what they accept as a plain array with a closed Kind vocabulary; child schemas are reported as they are. TypeExpression is the single translator of the Expect::type() language into that array and follows Validators::is() exactly (an unknown name is a class, 'int[]' is any iterable of ints, legacy validator names are Other). JsonSchema::export() is a pure function over describe() and refuses PHP-only types instead of emitting a schema the Processor would reject. Everything is @internal for now so the vocabulary can still change. | | | |
| http | by dg | uses #Deprecated wip | | | |
| http | by dg | removed samesite check using cookie (BC break) | | | |
| http | by dg | IRequest, IResponse: added typehints, unification (BC break) | | | |
| http | by dg | SessionSection: removed $warnOnUndefined (BC break) | | | |
| http | by dg | Response: passing 0 as the expiration to setCookie() is deprecated 0 historically meant a session cookie; null now expresses that explicitly. 0 is still accepted for BC but emits a deprecation notice. | | | |
| http | by dg | silently deprecated methods trigger E_USER_DEPRECATED | | | |
| http | by dg | removed deprecated stuff | | | |
| http | by dg | opened 4.0-dev | | | |
| http | by dg | RequestFactory: added setBaseUrl() and 'http: baseUrl' option as a fallback for CLI When the application runs from the command line (cron, tasks, MCP server), $_SERVER carries no host, so the request URL was meaningless and everything derived from it (%baseUrl%, LinkGenerator, template $baseUrl, assets) broke. The base URL is used only when no host can be detected from the environment, so a web application on any domain keeps working without changes. http: baseUrl: https://example.com/ | | | |
| http | by dg | Response::setCookie() treats an explicitly empty domain or path as given The path/domain defaulting used truthy checks, so an explicit '' (a host-only cookie or an empty path) behaved as if the argument was omitted: the cookie inherited cookiePath instead of widening to '/', or cookieDomain instead of staying host-only. Only null now means "not given". | | | |