Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
165 lines (129 sloc) 3.79 KB
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Nette\Application\UI;
use Nette;
/**
* Web form adapted for Presenter.
*/
class Form extends Nette\Forms\Form implements ISignalReceiver
{
/** @var callable[]&(callable(Form $sender): void)[]; Occurs when form is attached to presenter */
public $onAnchor;
/** @var bool */
private $sameSiteProtection = true;
/**
* Application form constructor.
*/
public function __construct(Nette\ComponentModel\IContainer $parent = null, string $name = null)
{
parent::__construct();
if ($parent !== null) {
$parent->addComponent($this, $name);
}
}
protected function validateParent(Nette\ComponentModel\IContainer $parent): void
{
parent::validateParent($parent);
$this->monitor(Presenter::class, function (Presenter $presenter): void {
if (!isset($this->getElementPrototype()->id)) {
$this->getElementPrototype()->id = 'frm-' . $this->lookupPath(Presenter::class);
}
if (!$this->getAction()) {
$this->setAction(new Link($presenter, 'this'));
}
$controls = $this->getControls();
if (iterator_count($controls) && $this->isSubmitted()) {
foreach ($controls as $control) {
if (!$control->isDisabled()) {
$control->loadHttpData();
}
}
}
$this->onAnchor($this);
});
}
/**
* Returns the presenter where this component belongs to.
*/
final public function getPresenter(): ?Presenter
{
if (func_num_args()) {
trigger_error(__METHOD__ . '() parameter $throw is deprecated, use getPresenterIfExists()', E_USER_DEPRECATED);
$throw = func_get_arg(0);
}
return $this->lookup(Presenter::class, $throw ?? true);
}
/**
* Returns the presenter where this component belongs to.
*/
final public function getPresenterIfExists(): ?Presenter
{
return $this->lookup(Presenter::class, false);
}
/** @deprecated */
public function hasPresenter(): bool
{
return (bool) $this->lookup(Presenter::class, false);
}
/**
* Tells if the form is anchored.
*/
public function isAnchored(): bool
{
return $this->hasPresenter();
}
/**
* Disables CSRF protection using a SameSite cookie.
*/
public function disableSameSiteProtection(): void
{
$this->sameSiteProtection = false;
}
/**
* Internal: returns submitted HTTP data or null when form was not submitted.
*/
protected function receiveHttpData(): ?array
{
$presenter = $this->getPresenter();
if (!$presenter->isSignalReceiver($this, 'submit')) {
return null;
}
$request = $presenter->getRequest();
if ($request->isMethod('forward') || $request->isMethod('post') !== $this->isMethod('post')) {
return null;
}
if ($this->isMethod('post')) {
return Nette\Utils\Arrays::mergeTree($request->getPost(), $request->getFiles());
} else {
return $request->getParameters();
}
}
protected function beforeRender()
{
parent::beforeRender();
$key = ($this->isMethod('post') ? '_' : '') . Presenter::SIGNAL_KEY;
if (!isset($this[$key])) {
$do = $this->lookupPath(Presenter::class) . self::NAME_SEPARATOR . 'submit';
$this[$key] = (new Nette\Forms\Controls\HiddenField($do))->setOmitted();
}
}
/********************* interface ISignalReceiver ****************d*g**/
/**
* This method is called by presenter.
*/
public function signalReceived(string $signal): void
{
if ($signal !== 'submit') {
$class = get_class($this);
throw new BadSignalException("Missing handler for signal '$signal' in $class.");
} elseif ($this->sameSiteProtection && !$this->getPresenter()->getHttpRequest()->isSameSite()) {
$this->getPresenter()->detectedCsrf();
} elseif (!$this->getPresenter()->getRequest()->hasFlag(Nette\Application\Request::RESTORED)) {
$this->fireEvents();
}
}
}
You can’t perform that action at this time.