| 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". | | | |
| http | by dg | HttpExtension: default to trusting X-Forwarded-For only (BC break!) Changes the configured default of `proxyHeaders` from "both" to "xForwarded", so an application behind a proxy no longer trusts a client-supplied "Forwarded" header by default (the common proxy sets X-Forwarded-For). The RequestFactory PHP default is intentionally left at "both" for BC; this hardens only the framework configuration. BC: deployments whose proxy uses the "Forwarded" header must now set `proxyHeaders: forwarded` (or `both`). | | | |
| http | by dg | RequestFactory: configurable trust of forwarding headers Adds a choice of which forwarding headers to trust from a trusted proxy: setProxy() gains $forwarded and $xForwarded flags, and the DI extension exposes it as `proxyHeaders: both|xForwarded|forwarded|none`, mapped to the two flags. Lets a deployment ignore a header its proxy does not manage (e.g. a client-supplied "Forwarded" while the proxy only sets "X-Forwarded-For"). Default stays "both" (Forwarded preferred) — no behaviour change. | | | |
| http | by dg | RequestFactory: reworks trusted-proxy forwarding resolution Resolves the real client address, scheme and host from forwarding headers correctly and consistently for both "Forwarded" and "X-Forwarded-*": - Parses "Forwarded" into RFC 7239 hops instead of flattening "," and ";" together, so proto/host are taken from the same hop as the selected client address (removes the crude single-value guard that discarded them on any multi-hop header). - Picks the client address by stripping trailing trusted proxies and taking the rightmost remaining hop, instead of blindly trusting the leftmost, client-spoofable "for" value. - Validates the resolved address as an IP; an unknown/obfuscated identifier or a broken chain now yields null instead of a non-IP string. The stripping and validation is shared by both paths via findClientHop(). Note: as before, this trusts whatever forwarding header the request carries. The trusted proxy must set the header it uses and strip any client-supplied forwarding header it does not, otherwise a passed-through header (e.g. a client "Forwarded" while the proxy only manages "X-Forwarded-For") is trusted. BC: getRemoteAddress() now returns null (not a non-IP string) when the innermost forwarded value is not a valid IP address. | | | |
| http | by dg | added AGENTS.md & DOCS | | | |
| http | by dg | CI: switched Coveralls upload to the official action The php-coveralls phar is replaced by coverallsapp/github-action, which resolves the token and the absolute paths in the Clover report on its own, so tests/.coveralls.yml is no longer needed. Coverage is now uploaded even when tests crash under phpdbg. Being phpdbg-compatible is not a goal, but until now the failing step aborted the job before the upload ever ran. The job-level continue-on-error is gone, so genuine failures, including a rejected upload, are visible. | | | |
| http | by dg | phpstan: fixes | | | |
| http | by dg | improved phpDoc | | | |
| http | by dg | only compiler-optimized functions in use-function imports | | | |
| di | by dg | removed Statement compatibility shims from expression classes WIP | | | |
| di | by dg | deprecated magic properties (BC break) | | | |
| di | by dg | removed compatibility for old class names | | | |
| di | by dg | removed Definition::generateMethod() (BC break) | | | |
| di | by dg | removed deprecated stuff - %parameters% - three ... dots - @inject & @var | | | |
| di | by dg | opened 4.0-dev | | | |
| di | by dg | ParametersExtension: nested dynamic parameters are addressed by key paths, dotted strings keep their flat meaning (BC) setDynamicParameterNames() entries are now shape-driven: a string stands for itself (a plain top-level name in which a dot has no special meaning, as before), a list of keys addresses a nested value. DynamicValue markers resolve to key paths as well. This removes the reinterpretation of user-supplied dotted names introduced with the dotted-name feature, at both places where it happened: the marker literal injection (getRef over exploded name) and the config default lookup in the generated fallback. The runtime name of a path is its dot-joined form; the dot-in-key guard moved to the single name<->path mapping point and newly covers explicit paths too. Claude-Session: https://claude.ai/code/session_01HcUe1zbekTPjU5LuCkxgFT | | | |
| di | by dg | ParametersExtension: dynamic parameters via DynamicValue marker and dotted names WIP setDynamicParameterNames() now accepts dotted names (e.g. 'db.password'), marking a value nested inside a parameter as dynamic; the marker literal is injected at that position and the promoted top-level key regenerates its subtree at runtime, so sibling values stay compiled in. Adds Nette\DI\DynamicValue, an inline marker usable directly in the parameters config at any depth; the extension derives its dotted name from its position. Its optional value is the default used when no runtime value is supplied. The value is excluded from serialization so a per-request value (e.g. from nette/bootstrap) cannot bust the cache. | | | |
| di | by dg | Definitions: the previous-generation API is deprecated Deprecated in favour of the canonical vocabulary (removal planned for 4.0): - addDefinition() and add*Definition() -> add() with factory()/accessor()/locator()/imported() - getDefinition()/getDefinitions()/hasDefinition()/removeDefinition() -> get()/getAll()/has()/remove() - getByType() -> has(type:) or get(type:)->getName() - getDefinitionByType() -> get(type:) - findByType()/findByTag() -> find(type:)/find(tag:) with Definition::getTag() - literal() -> Nette\DI\code() - addExcludedClasses() -> excludeFromAutowiring() - addTag()/setAutowired() -> tag()/autowired() - setFactory()/getFactory() -> setCreator()/getCreator() - addSetup() -> setup(); setSetup() -> clearSetup() and setup() - getImplement() -> getType() The canonical methods no longer route through the deprecated ones: the lookup primitives moved to private lookupByName()/lookupByType()/findAllByType()/ hasName()/removeByName(). The remaining internal uses of the old accessors (Resolver, ServicesExtension, DefinitionSchema) are the compilation machinery these wrappers delegate to; they become internal in 4.0. | | | |
| di | by dg | Definition::getName() returns string (BC break) [WIP] | | | |
| di | by dg | FactoryDefinition API | | | |
| di | by dg | Definitions: the canonical decade API ContainerBuilder / Nette\DI\Definitions: - add() takes an optional type: (mirrors NEON's create:/type: sibling keys) and preserves the concrete definition class via @template; type: cannot be combined with a ready-made definition - has() addresses by tag: too; get()/find()/has()/remove() complete the addressing matrix (get/remove take unique addresses, find multi ones, has any) - a backslashed positional name in get()/has() throws an instructive error instead of silently failing (a service name never contains a backslash) - excludeFromAutowiring() supersedes addExcludedClasses() - the registration primitive moved to private registerDefinition(); public addDefinition() and the four add*Definition() helpers now delegate to it Definitions: - getName() returns non-nullable string (the name is an invariant of registration); the compilation machinery distinguishes unregistered definitions (e.g. factory result definitions) via the new @internal tryGetName() - exported() replaces the never-released setExported() - the canonical verbs own the bodies: tag(), autowired(), setup(); the old names delegate to them - FactoryDefinition gained setCreator()/setup()/setArguments() delegating to the result definition (mirrors NEON, where create:/setup:/arguments: on a factory configure the produced service, while tags:/autowired: belong to the factory) Nette\DI functions: - factory(), accessor(), locator() build the concrete generated-definition kinds (typed, one word = one meaning); implement() remains as the shape-detecting dispatcher for runtime-unknown interfaces | | | |
| di | by dg | CompilerExtension: onStartup() adds DSL expressions / code to initialize() onStartup(Expression|string $code, array $args = []) is the clean, first-class way to add startup code to the container's initialize() method - a full replacement for the verbose $this->initialization->addBody($builder-> formatPhp(...)) dance. It accepts a DSL expression (e.g. service('session')->method('start')) or a PHP statement string with ? placeholders whose args may themselves be DSL expressions; both are completed and generated via ContainerBuilder::formatPhp(), which is un-deprecated as the DI-aware statement formatter behind it. Built-in DIExtension and ParametersExtension migrated to onStartup() as reference examples. This is the CompilerExtension-level onStartup (for extensions), distinct from the deferred Definitions-level one (for config closures). | | | |
| di | by dg | Extensions: rewritten to the Definitions DSL (DIExtension, DecoratorExtension, InjectExtension, SearchExtension) | | | |