Předání getParameter do FormFactory

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kiCkZ
Člen | 153
+
0
-

Ahoj,

chtěl bych se zeptat, jak předáváte getParameter do továrny ?
Potřebuji získat ID z URL, nicméně nevim jak to předat z presenteru do FormFactory.

Děkuji

CZechBoY
Člen | 3608
+
+1
-

Většinou přes property.

class MujPresenter extends Presenter
{
	private $id;

	public function actionDefault($id)
	{
		// validace id
		$this->id = (int)$id;
	}

	protected function createComponentXXX()
	{
		return $this->factory->create($this->id);
	}
}
kiCkZ
Člen | 153
+
0
-

CZechBoY napsal(a):

Většinou přes property.

class MujPresenter extends Presenter
{
	private $id;

	public function actionDefault($id)
	{
		// validace id
		$this->id = (int)$id;
	}

	protected function createComponentXXX()
	{
		return $this->factory->create($this->id);
	}
}

Prosimtě a jak by si to napsal jsem, protože toto mi přijde nyní nepoužitelné, zkusil jsem to a samozřejmě mi to píše, že to volá callable $onsuccess.

ArticlePresenter.php

namespace App\Presenters;

use Nette;

class ArticlePresenter extends BasePresenter {

    /** @var \App\Model\ArticleManager @inject */
    public $model;

    /** @var \App\Forms\ArticleFormFactory @inject */
    public $articleFactory;

    public function renderShow() {
        $this->template->article = $this->model->show();
    }

    protected function createComponentArticleForm() {
        return $this->articleFactory->create(function(){
            $this->flashMessage('Článek byl úspěšně vytvořen');
        });
    }

    public function actionEdit($id) {
        $article = $this->model->get($id);
        if(!$article){
            $this->error('Článek nebyl nalezen');
        }
        $this['articleForm']->setDefaults($article->toArray());
    }
}

ArticleFormFactory.php

namespace App\Forms;

use Nette;
use Nette\Application\UI\Form;
use App\Model\ArticleManager;

class ArticleFormFactory {

    use Nette\SmartObject;

    /** @var FormFactory */
    private $factory;

    /** @var ArticleManager */
    private $model;

    public function __construct(FormFactory $factory, ArticleManager $model) {
        $this->factory = $factory;
        $this->model = $model;
    }

    public function create(callable $onSuccess) {
        $form = $this->factory->create();
        $form->addText('title','Název článku')
             ->setRequired();
        $form->addText('url','URL adresa');
        $form->addTextArea('content','');
        $form->addSubmit('save','Vytvořit');
        $form->onSuccess[] = function (Form $form,$values) use ($onSuccess) {
            try{
                $this->model->add($values->title,$values->url,$values->content);
            } catch (Exception $e) {
                $form->addError('Nepodařilo se vytvořit článek');
                return;
            }
            $onSuccess();
        };
        return $form;
    }
}
CZechBoY
Člen | 3608
+
0
-

Vypadá to v pohodě. Co ti to kde píše za chybu?

matopeto
Člen | 395
+
0
-

mas:

public function create(callable $onSuccess) {

ale predavas mu tam (int)id vid $this->factory->create($this->id);

Preto ti to nejde.

kiCkZ
Člen | 153
+
0
-

Jakým způsobem to pak přidáš do té továrny ?
I když jsem nastavil $id do parametru ProfileForm, tak mi to nefunguje.

David Matějka
Moderator | 6445
+
0
-

tak mi to nefunguje.

co to znamena? hlasi to chybu? ukaz, jak to mas ted..

kiCkZ
Člen | 153
+
0
-

David Matějka napsal(a):

tak mi to nefunguje.

co to znamena? hlasi to chybu? ukaz, jak to mas ted..

Chybu to nehlásí, protože to není dokončené, ale vždy po nějakých pokusech mi to hlásilo, že je proměnná ID v
továrně nedefinována, takže se z presenteru nepředala.

ArticlePresenter

	public $article;

	public function renderDefault(int $articleId) {
    $this->article = $this->model->get($articleId);
}

protected function createComponentArticleForm() {
    return $this->articleFactory->create($this->article,function(){
        $this->flashMessage('Článek byl úspěšně vytvořen','success');
        $this->redirect('show');
    });
}

ArticleFormFactory

public function create($id,callable $onSuccess) {
       $form = $this->factory->create();
       $form->addText('title','Název článku')
            ->setRequired();
       $form->addText('url','URL adresa');
       $form->addTextArea('content','');
       $form->addSubmit('save','Vytvořit');
       $form->onSuccess[] = function (Form $form,$values) use ($onSuccess) {
           try{
				// sem potřebuji předat to $ID a vytvořit podmínku pro update
               $this->model->add($values->title,$values->url,$values->content);
           } catch (Exception $e) {
               $form->addError('Nepodařilo se vytvořit článek');
               return;
           }
           $onSuccess();
       };
       return $form;
   }

Editoval kiCkZ (7. 9. 2017 13:17)

Rob Bob
Člen | 60
+
0
-

Musíš si to předat ještě zvlášť do toho callbacku, tedy vložit do use, tím mu řekneš jaké lokální proměnné může použít, protože má jiný scope.

<?php
$form->onSuccess[] = function (Form $form,$values) use ($id, $onSuccess) { // tady změna
           try{
               // sem potřebuji předat to $ID a vytvořit podmínku pro update
               $this->model->add($values->title,$values->url,$values->content);
           } catch (Exception $e) {
               $form->addError('Nepodařilo se vytvořit článek');
               return;
           }
           $onSuccess();
       };

?>

Editoval Rob Bob (7. 9. 2017 14:39)

matopeto
Člen | 395
+
0
-

Nezabudni za v tvojom $id je article $this->articleFactory->create($this->article,function() ... a nie iba id ako by to vyzeralo z public function create($id,callable $onSuccess) {, aby si nepisal ze ti to zasa nejde :)

kiCkZ
Člen | 153
+
0
-

matopeto napsal(a):

Nezabudni za v tvojom $id je article $this->articleFactory->create($this->article,function() ... a nie iba id ako by to vyzeralo z public function create($id,callable $onSuccess) {, aby si nepisal ze ti to zasa nejde :)

Ano to vim, nicméně i přesto to nefunguje.

Presenter:

public $article;

   public function renderDefault(int $articleId) {
       $this->article = $this->model->get($articleId);
   }

   public function renderShow() {
       $this->template->article = $this->model->show();
   }

   protected function createComponentArticleForm() {
       return $this->articleFactory->create($this->article,function(){
           $this->flashMessage('Článek byl úspěšně vytvořen','success');
           $this->redirect('show');
       });
   }

Factory

public function create($article,callable $onSuccess) {
        $form = $this->factory->create();
        $form->addText('title','Název článku')
             ->setRequired();
        $form->addText('url','URL adresa');
        $form->addTextArea('content','');
        $form->addSubmit('save','Vytvořit');
        $form->onSuccess[] = function (Form $form,$values) use ($article,$onSuccess) {
            try{
                if($article) {
                    $articl = $this->model->get($article);
                    $articl->update($values);
                } else {
                    $this->model->add($values->title,$values->url,$values->content);
                }
            } catch (Exception $e) {
                $form->addError('Nepodařilo se vytvořit článek');
                return;
            }
            $onSuccess();
        };
        return $form;
    }

Manager

public function get($id) {
    return $this->database->table(self::TABLE_NAME)->get($id);
}

public function update($values) {
    try {
        $this->database->table(self::TABLE_NAME)->update($values);
    } catch (Exception $e) {

    }
}

Editoval kiCkZ (7. 9. 2017 14:30)

CZechBoY
Člen | 3608
+
+2
-

Protože si udělal přesně to o čem psal @matopeto.
Zdá se mi, že si velmi škodíš tím, že vůbec nečteš co kdo píše.

kiCkZ
Člen | 153
+
0
-

CZechBoY napsal(a):

Protože si udělal přesně to o čem psal @matopeto.
Zdá se mi, že si velmi škodíš tím, že vůbec nečteš co kdo píše.

Já to čtu, nicméně prostě nechápu co je špatně.
To znamená, že v tom ID mam tedy celý article konkrétní, ale jak mam tedy zavolat na ID.
Uvědom si, že ten framework taky tuhle dokumentaci k takovým to případům ani nemá.

Editoval kiCkZ (7. 9. 2017 14:26)

David Matějka
Moderator | 6445
+
0
-

v tom $article, co si tam predavas nemas id, ale uz ten clanek, tudiz tento kod nebude fungovat, respektive je zbytecny:

if($article) {
    $articl = $this->model->get($article);
    $articl->update($values);
}

a muzes to nahradit za

if($article) {
    $article->update($values);
}
kiCkZ
Člen | 153
+
0
-

David Matějka napsal(a):

v tom $article, co si tam predavas nemas id, ale uz ten clanek, tudiz tento kod nebude fungovat, respektive je zbytecny:

if($article) {
    $articl = $this->model->get($article);
    $articl->update($values);
}

a muzes to nahradit za

if($article) {
    $article->update($values);
}

Stále mi to místo update dělá insert, jak kdyby to nedetekovalo, že to má upravit přímo tento článek.

Rob Bob
Člen | 60
+
0
-

kiCkZ napsal(a):

CZechBoY napsal(a):

Protože si udělal přesně to o čem psal @matopeto.
Zdá se mi, že si velmi škodíš tím, že vůbec nečteš co kdo píše.

Já to čtu, nicméně prostě nechápu co je špatně.
To znamená, že v tom ID mam tedy celý article konkrétní, ale jak mam tedy zavolat na ID.
Uvědom si, že ten framework taky tuhle dokumentaci k takovým to případům ani nemá.

https://doc.nette.org/…ase/explorer

Tam je na začátku ActiveRow, k jeho datům můžeš překvapivě přistupovat přímo voláním $row->property

kiCkZ
Člen | 153
+
0
-

Rob Bob napsal(a):

kiCkZ napsal(a):

CZechBoY napsal(a):

Protože si udělal přesně to o čem psal @matopeto.
Zdá se mi, že si velmi škodíš tím, že vůbec nečteš co kdo píše.

Já to čtu, nicméně prostě nechápu co je špatně.
To znamená, že v tom ID mam tedy celý article konkrétní, ale jak mam tedy zavolat na ID.
Uvědom si, že ten framework taky tuhle dokumentaci k takovým to případům ani nemá.

https://doc.nette.org/…ase/explorer

Tam je na začátku ActiveRow, k jeho datům můžeš překvapivě přistupovat přímo voláním $row->property

Jako zatím mi nikdo moc nepomohl, stále to dělá to samé špatně.
Mam URL přes actionEdit se prokliknu do článku a chci po uložení editovat jen tento záznam.

 public function renderDefault() {
		// změnil jsem volání na get, aby mi to dalo id z URL je to v pořádku ?
        $this->id= $this->getParameter('articleId');
}

Poté to předám sem:

protected function createComponentArticleForm() {
        return $this->articleFactory->create($this->id,function(){
            $this->flashMessage('Článek byl úspěšně vytvořen','success');
            $this->redirect('show');
        });
    }
public function create($id,callable $onSuccess) {
        $form = $this->factory->create();
        $form->addText('title','Název článku')
             ->setRequired();
        $form->addText('url','URL adresa');
        $form->addTextArea('content','');
        $form->addSubmit('save','Vytvořit');
        $form->onSuccess[] = function (Form $form,$values) use ($id,$onSuccess) {
            try{
                if($id) {
					$article = $this->model->get($article);
                    $article->update($values);
                } else {
                    $this->model->add($values->title,$values->url,$values->content);
                }
            } catch (Exception $e) {
                $form->addError('Nepodařilo se vytvořit článek');
                return;
            }
            $onSuccess();
        };
        return $form;
    }
David Matějka
Moderator | 6445
+
0
-

@kiCkZ

  1. zkontroluj si, v jake akci jsi. nekde vyse to vypada, ze v „edit“, ale tady pouzivas „default“
  2. musi to byt v action* a ne v render* metode
matopeto
Člen | 395
+
+2
-

Jako zatím mi nikdo moc nepomohl, stále to dělá to samé špatně.

Zatial sme ti poradili so vsetkym co ti neslo, dokonca i prvotna otazka bola zodpovedana hned. To ze ti to nejde/nevies nasrubovat na svoj projekt, ktory nam tu kuskujes po kuskoch kodu a nam sa tazko radi, ked nevieme aky mas kod ani coho ches dosiahnut. Dalsia vec je ze robis preklepy (ktore sme ti tiez vsetky poradili opravit) ale verim ze as ti to podari dokopat do konca z tych rad co tu mas :) – samozrejme v dobrom a bez urazky som to vsetko myslel.

Editoval matopeto (7. 9. 2017 15:31)

kiCkZ
Člen | 153
+
0
-

David Matějka napsal(a):

@kiCkZ

  1. zkontroluj si, v jake akci jsi. nekde vyse to vypada, ze v „edit“, ale tady pouzivas „default“
  2. musi to byt v action* a ne v render* metode

Tak ta action je v pořádku, ale i přesto mi to dává místo úpravy (update) stále create funkci.
Takto to aktuálně mam, nyní by si to mělo brát jen to ID z URL nikoliv celý článek.

	public function actionDefault($id) {
    $this->id = $this->getParameter($id);
}

public function renderShow() {
    $this->template->article = $this->model->show();
}

protected function createComponentArticleForm() {
    return $this->articleFactory->create($this->id,function(){
        $this->flashMessage('Článek byl úspěšně vytvořen','success');
        $this->redirect('show');
    });
}

public function actionEdit($id) {
    $article = $this->model->get($id);
    if(!$article){
        $this->error('Článek nebyl nalezen');
    }
    $this['articleForm']->setDefaults($article->toArray());
}
public function create($id,callable $onSuccess) {
        $form = $this->factory->create();
        $form->addText('title','Název článku')
             ->setRequired();
        $form->addText('url','URL adresa');
        $form->addTextArea('content','');
        $form->addSubmit('save','Vytvořit');
        $form->onSuccess[] = function (Form $form,$values) use ($id,$onSuccess) {
            try{
                if($id) {
                    $article = $this->model->get($id);
                    $article->update($values);
                } else {
                    $this->model->add($values->title,$values->url,$values->content);
                }
            } catch (Exception $e) {
                $form->addError('Nepodařilo se vytvořit článek');
                return;
            }
            $onSuccess();
        };
        return $form;
    }

Editoval kiCkZ (7. 9. 2017 15:42)

David Matějka
Moderator | 6445
+
+2
-

Tak ta action je v pořádku,

a proc tam mas jak actionDefault tak actionEdit? v jake akci teda provadis editaci clanku? default nebo edit?

$this->getParameter($id);

je spatne. to ti vrati hodnotu parametru s nazvem, ktery odpovida tomu ID. mas tam mit jen $this->id = $id

Rob Bob
Člen | 60
+
+2
-

Tak když voláš actionEdit, měl by sis to ID nastavit tam, ne?

public function actionEdit($id) {
	$this->id = $id; //změna
    $article = $this->model->get($id);
    if(!$article){
        $this->error('Článek nebyl nalezen');
    }
    $this['articleForm']->setDefaults($article->toArray());
}
kiCkZ
Člen | 153
+
0
-

Rob Bob napsal(a):

Tak když voláš actionEdit, měl by sis to ID nastavit tam, ne?

public function actionEdit($id) {
	$this->id = $id; //změna
    $article = $this->model->get($id);
    if(!$article){
        $this->error('Článek nebyl nalezen');
    }
    $this['articleForm']->setDefaults($article->toArray());
}

Davide i Robe děkuju moc konečně jsem to rozběhl, mam v tom trochu ještě guláš.
Snad to časem budu chápat více a půjde to samo :)