Form is not anchored and therefore can not determine whether it was submitted při přechodu na 2.4

BuMoRi
Člen | 109
+
0
-

Ahoj, při přechodu z 2.3 na 2.4 dostávám 500 a v logu mám: Form is not anchored and therefore can not determine whether it was submitted.<| in \libs\Nette\Forms\Form.php:400
Znamená to, že musím místo Nette\Forms\Form používat Nette\Application\UI\Form? Nebo by mohla být chyba jinde?

CZechBoY
Člen | 3608
+
0
-

Pokud používáš Forms\Form tak to může být ta chyba, možná to bude ještě něco jinýho.

BuMoRi
Člen | 109
+
0
-

Třídu Forms\Form jsem všude nahradil, ale žádná změna.
Jsou tam použity i např. třídy \Nette\Forms\Controls\BaseControl nebo \Nette\Forms\Controls\TextInput, to je OK?
Případně jak bych měl tuto chybu hledat/debugovat?

CZechBoY
Člen | 3608
+
0
-

Idealne kouknout tam kde se chyba vyskytuje a kdyztak poslat callstack pokud nebudes vědět.

BuMoRi
Člen | 109
+
0
-

Prosimtě callstack myslíš z Tracy? Mně totiž vyskočí 500, aniž by to spadlo do Tracy a jen v logu mám tu chybu.
Zkusím napsat kde chyba vzniká, jestli by tě něco napadlo:
Vytvoření formuláře je pomocí vlastní knihovny postavené na Nette

<?php
  protected function createComponentSearchForm($name)
  {
	$form = $this->addForm('searchForm');
	...
?>

Metoda addForm:

<?php
  public function addForm($name, $ajax=false, $display=true, $csrf=false)
  {
    $form = new \Ownlib\Forms\AppForm($this, $name);
	...
?>

Třída AppForm:

<?php
class AppForm extends \Ownlib\AppComponent
{
  /** @var \Nette\Application\UI\Form */
  private $form;
  ...
  public function __construct($parent = NULL, $name = NULL)
  {
    parent::__construct();

    $this->formname = $name;
    $this->form = new \Nette\Application\UI\Form($this, $this->formname);
    if ($this->form->isSubmitted()) {
      $this->handleShow(null);
      $this->invalidateControl();
    }
	...
?>

Tady jsem udělal oproti předchozím verzím změnu v tom, že parent construct je bez parametrů. Třída je poděděná ze třídy Component (2.4) a tam byly v constructoru v předchozích verzích Nette (2.1–2.3) 2 parametry – viz Component (2.3)

Padá mi to na té podmínce $this->form->isSubmitted(), kde mi metoda isAnchored() vrátí NULL, zatímco ve starších verzích mi vracela presenter.

Jsou tyto informace k něčemu? Budu vděčný za jakoukoliv pomoc.

David Matějka
Moderator | 6445
+
0
-

máš to celé divné, ale hlavní problém je, že smazáním těch parametrů pro parent::__construct si zrušil připojení do stromu komponent. jako hotfix pod to můžeš přidat pod to parent::__construct:

$parent->addComponent($this, $name);

ale bude lepší, když necháš připojování do stromu komponent na nette, tzn všude využiješ továrny na komponenty, takže v tom tvém Appform budeš mít

public function createComponentForm()
{
	$form = new UI\Form();
	...
	return $form;
}

to, co máš v té isSubmitted podmínce, můžeš dát do callbacku na onAnchor událost

BuMoRi
Člen | 109
+
0
-

Já jsem právě to čemu říkáš hotfix zkoušel, dle depracated hlášky „argument $parent is deprecated, use $parent->addComponent() instead.“
Ale bohužel dostávám tuto hlášku: PHP Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given.

CZechBoY
Člen | 3608
+
0
-

Asi bys nemohl celou tu appku někde zveřejnit co? :-)

BuMoRi
Člen | 109
+
0
-

To bych rád, ale nemůžu :(
Jinak je to hodně rozsáhlá appka, která byla původně psaná tušim ve 2.0, takže jak píše David, může tam být na dnešní dobu pár divných věcí… Ale až do verze 2.3 se to s menšími záseky delkem dařilo upgradovat.

CZechBoY
Člen | 3608
+
0
-

ok, no tak potom bych z toho udělal klasickou komponentu (pokud jde). Pokud nejde tak si počkej na attachnutí komponenty k presenteru.

BuMoRi
Člen | 109
+
0
-

CZechBoY napsal(a):

tak si počkej na attachnutí komponenty k presenteru.

A to znamená prosimtě přesně co? Myslel jsem že právě v tom je ten problém, že ten formulář není připojen k presenteru…

David Matějka
Moderator | 6445
+
+1
-

@BuMoRi viz ten muj komentar s onAnchor

BuMoRi
Člen | 109
+
0
-

Ahoj, zkusil jsem rady, které mi napsali CZechBoY a David, ale stále se to nedaří rozchodit:

1. Místo parametrů v constructoru přidat addComponent
výsledek:

<?php
PHP Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given in …\AppForm.php:302
Fatal Error: ReflectionClass::getMethod(): Internal error: Failed to retrieve the reflection object in ...\libs\Ownlib\Forms\AppForm.php:304
?>

V AppForm zmíněné řádky:

<?php
final public function __call($procedureName, $arguments=array())
  {
    try {
      $ref = new \ReflectionObject($this->form); //řádek 302
      $ret = null;
      if (!$ref->getMethod($procedureName)) throw new \Exception('Procedure `'.$procedureName.'` doesn`t exist!'); //řádek 304
?>

2. Továrna: vyhazuje stejné chyby, jako když formulář vytvářím v constructoru

3. Dal jsem místo isSubmitted podmínky: $this->onAnchor[] = function() {…
Dostávám

<?php
[Nette\UnexpectedValueException]: |>Method homePresenter::createComponentSearchForm() did not return or create the desired component.<| in \libs\Nette\ComponentModel\Container.php:176
?>

Nevím jestli jsem to s onAnchor správně pochopil. Také jsem zapomněl napsat, že metoda addForm je v Presenteru, který je rodič všech BasePresenterů v jednotlivých modulech.
Prosím o radu, jestli jstem onAnchor správně použil, případně co ještě zkusit…

David Matějka
Moderator | 6445
+
0
-
  1. to je tvuj kod, takze dle callstacku zjisti, odkud se to vola a jakto, ze je this->form prazdne
  2. tak z te metody vrat komponentu, viz https://doc.nette.org/…n/presenters#…
BuMoRi
Člen | 109
+
0
-

ad 1: aha, takže ten „hotfix“

<?php
$parent->addComponent($this, $name);
?>

musím dát až pod vytvoření formuláře, tzn. řádek

<?php
$this->form = new \Nette\Application\UI\Form($this, $this->formname);
?>

Tak snad se už konečně někam posunu…, dík.