Framework

Repository Author Commit message Committed SHA  
 
forms by dg netteForms: a form whose repeater starts empty validates on submit

Removing a repeater item refreshes the toggles.

forms by dg setSubmissionSource() loads repeaters, so they work in forms anchored to a presenter

Their monitor fires before the form is anchored and never loaded the data.
Loading may detach surplus items, so membership is re-checked per component.

forms by dg Repeater: number of items built from a submitted request is capped

A forged POST cannot invoke an expensive factory hundreds of times; at most
max + reserve containers are built. addRepeater() accepts the bounds, so the
cap applies from the start.

forms by dg DateTimeControl: Equal compares dates and times in the precision of the control

It crashed on the string cast of the date object. Like Range, it is decided
by the control, so a date ignores the time part and a time compares by the
time of day, the same as the client does.

application by dg Control: flashMessage() does not create the template

In the most typical flow - flashMessage() followed by redirect() - the template
was created just to be thrown away, which builds a whole Latte\Engine instance.
The messages are written to the session first and into the template only if it
already exists; a template created later gets them from the template factory,
which reads the flashes from the session on its own.

application by dg AccessPolicy: class-level #[Requires] is inherited from ancestors

ReflectionClass::getAttributes() does not return attributes of parent classes,
so a rule placed on a common ancestor (a typical #[Requires(sameOrigin: true)]
on BaseAdminPresenter) was silently not enforced in its descendants. Attributes
are now collected along the whole ancestor chain; a rule explicitly set in a
descendant overrides the same rule of its ancestors.

application by dg Presenter::argsToParams() now distinguish between NULL and ''
application by dg removed {templatePrint}
application by dg uses nette/routing 4.0
application by dg RoutingPanel: added support for AI agents
application by dg removed support for @annotations (BC break)
application by dg Presenter: removed constructor (BC break!)
application by dg Component: only UI components can be added to presenter/component (BC break) WIP
application by dg Component: method checkRequirements() is called for createComponent<Name>() methods (BC break)
application by dg Revert "UI\PresenterComponent: removed references created by loadState() for persistent parameters. [Closes nette/nette#703][Closes nette/nette#703][Closes #69]" (possible BC break)

This reverts commit cda17f460d020b0f042364d4e140742022a7e94d.

See https://forum.nette.org/cs/35528-stejne-pojmenovany-parametr-akce-presenteru-a-persistentni-odlisne-chovani-v-nette-2-0-oproti-aktualnimu#p221742

BC break: Property must be nullable, ie: #[Persistent] public ?int $foo

application by dg removed legacy services names (BC break)
application by dg Presenter::handleInvalidLink() -> processInvalidLink() (BC break)
application by dg added type hints (BC break)
application by dg composer: increased dependencies versions
application by dg opened 4.0-dev
application by dg UI\Form: adapted to the SubmissionSource model of nette/forms 4.0

The form no longer overrides receiveHttpData(), isAnchored() and
beforeRender(); instead it overrides createDefaultSource() to return
null and sets the @internal FormSubmissionSource when anchored to
a presenter. The source detects submission via the 'submit' signal,
reads the application request and installs the hidden signal field in
its prepare() render hook; it resolves the presenter from the form
lazily, so a form re-anchored to another presenter keeps working. The
catch-up pass of setSubmissionSource() replaces the manual
loadHttpData() loop in validateParent().

The form owns its cross-origin state (private ?FetchSite $allowedOrigin
+ allowCrossOrigin()) independently of nette/forms; the same-origin
check intentionally stays in signalReceived(), where a failure is
reported via Presenter::detectedCsrf().

Requires nette/forms 4.0.

application by dg UI\Form: compatible with both nette/forms 3.x and the upcoming 4.0

Two forward-compatible additions to the classic presenter form:

- The form owns its cross-origin state (private ?FetchSite
$allowedOrigin + allowCrossOrigin()) instead of relying on the
protected $crossOrigin inherited from Nette\Forms\Form. Forms 3.x
declares that property untyped while 4.0 removes it, so no
redeclaration can satisfy both; a differently named private property
works with either version.
- createDefaultSource() returns null, which under forms 4.0 prevents
the lazy default HttpSource from materializing (the form is anchored
via the presenter). Under 3.x the method is unused; its return type
references an interface that only exists in 4.0, which is safe
because without a parent method there is no variance check.

The classic receiveHttpData()/isAnchored()/beforeRender() overrides
double as the documented BC seam of forms 4.0, so a single class works
with both major versions.

application by dg RoutingPanel: fixes lost {else} branch and missing space in tab

The conversion of the panel templates to Latte turned a ternary into an {if}
without the {else} branch, so non-string defaults and parameters were not
rendered at all, while string ones were rendered twice (escaped text plus the
full dump). The tab lost the space before the signal name.

application by dg UIExtension: adds getCacheKey() depending on the snippet attribute

SnippetNode::$snippetAttribute affects the generated code, but the extension did
not report it in the cache key, so changing it left stale compiled templates
with the original attribute.

application by dg UIExtension: findNonce() accepts a base64url nonce

The character class did not include '-', so a base64url nonce (emitted by common
CSP middlewares) was matched truncated and n:nonce then rendered a wrong value,
silently blocking the scripts. A nonce at the very beginning of the header was
not matched at all.

application by dg ComponentReflection: getActionRenderMethod() caches negative results too

The ??= operator never caches a null result, so for actions without an action*()
or render*() method the whole reflection lookup was repeated for every generated
link.

application by dg Presenter: detects an infinite loop of switch() calls

Two actions switching to each other (actionA() switches to 'b', actionB()
switches back to 'a') looped forever. As the target of switch() may depend on
request parameters, this was remotely triggerable.

bootstrap by dg used #Deprecated
bootstrap by dg renamed PhpExtension -> PhpIniExtension
bootstrap by dg opened 4.0-dev
bootstrap by dg added upgrading.md
bootstrap by dg added AGENTS.md & DOCS

Last synchronization: 2026-10-28 08:02:57