Cannot read an undeclared property: SignUpFormFactory
- XpresS
- Člen | 4
Ahojte,
Som v nette úplne nový a už druhý deň sa neúspešne pokúšam spraviť
registráciu cez DB
SignPresenter
protected function createComponentSignUpForm()
{
return $this->SignUpFormFactory->create(function () {
$this->redirect('Homepage:');
}
);
}
SignUpFormFactory.php
<?php
namespace App\Forms;
use App\Model;
use Nette;
use Nette\Application\UI\Form;
class SignUpFormFactory
{
use Nette\SmartObject;
const PASSWORD_MIN_LENGTH = 7;
/** @var FormFactory */
private $factory;
/** @var Model\UserManager */
private $userManager;
public function __construct(FormFactory $factory, Model\UserManager $userManager)
{
$this->factory = $factory;
$this->userManager = $userManager;
}
/**
* @return Form
*/
public function create(callable $onSuccess)
{
$form = $this->factory->create();
$form->addText('username', 'Pick a username:')
->setRequired('Please pick a username.');
$form->addEmail('email', 'Your e-mail:')
->setRequired('Please enter your e-mail.');
$form->addPassword('password', 'Create a password:')
->setOption('description', sprintf('at least %d characters', self::PASSWORD_MIN_LENGTH))
->setRequired('Please create a password.')
->addRule($form::MIN_LENGTH, null, self::PASSWORD_MIN_LENGTH);
$form->addSubmit('send', 'Sign up');
$form->onSuccess[] = function (Form $form, $values) use ($onSuccess) {
try {
$this->userManager->add($values->username, $values->email, $values->password);
} catch (Model\DuplicateNameException $e) {
$form['username']->addError('Username is already taken.');
return;
}
$onSuccess();
};
return $form;
}
}
Chybové hlásenie v Tracy:
**Nette\MemberAccessException
Cannot read an undeclared property App\Presenters\SignPresenter::$SignUpFormFactory.**
-- Chápem, že nemôže prečitať nedeklarovanú „vlastnosť“
Predom ďakujem za každú radu.
Editoval XpresS (25. 2. 2018 15:15)
- Ondřej Kubíček
- Člen | 494
tipuji že v tom SignPresenteru tu SignUpFormFactory neinjectuješ, pro presenter je nejjednoduší tenhle způsob:
/** @var App\Forms\SignUpFormFactory @inject **/
public $SignUpFormFactory;
- steelbull
- Člen | 241
Skontroluj, či máš v presenteri SignUpFormFactory injectnuté. Či máš v commente @inject a či je SignUpFormFactory nastavené na public. Tiež, či ho máš továrničku zaregistrovanú v neone.
Neviem, či do create môžeš vkladať anonymnú funkciu.
Mal by si tam mať len: $this->SignUpFormFactory->create(); a presmerovanie môžeš urobiť priamo v komponente v metóde $form->onSuccess[] = function() {redirect…}
- XpresS
- Člen | 4
@steelbull pravda, mal som to dať priamo do FormSucceeded a bolo by pokoj, ale mám problem, že mi z dajakého dôvodu component so signUpForm neexistuje,
RegisterPresenter.php
<?php
namespace App\Presenters;
use Nette;
use Nette\Application\UI\Form;
use Nette\Security\Passwords;
class RegisterPresenter extends Nette\Application\UI\Presenter
{
/**@var Nette\Database\context */
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
}
protected function createComponentSignUpForm()
{
$form = new Form;
$form->addEmail('email', 'E-mail')
->setRequired('Prosím vyplňte e-mail')
->addRule(function ($control) {
return !$this->database->query('SELECT email FROM users WHERE email = ? LIMIT 1', $control->value)->fetch();
}, 'Uživatel existuje');
$form->addText('username', 'Uživatelské jméno:')
->setRequired('Prosím vyplňte své uživatelské jméno.')
->addRule(function ($control) {
return !$this->database->query('SELECT username FROM users WHERE username = ? LIMIT 1', $control->value)->fetch();
}, 'Uživatel existuje');
$form->addPassword('password', 'Heslo:')
->setRequired('Prosím vyplňte své heslo.')
->addRule(Form::MIN_LENGTH, 'Minimální délka hesla je %d znaků', 1);
$form->onSuccess[] = [$this, 'registrationFormSucceeded'];
$form->addSubmit('send', 'Prihlásiť');
return $form;
}
public function registrationFormSucceeded($form, $values)
{
$values["password"] = Passwords::hash($values['password']);
$values["role"] = 'registred';
$this->database->table('users')->insert($values);
$this->flashMessage('Byl jste zaregistrován', 'success');
$this->redirect('Homepage:');}
}
TRACY:
** /* line 4 */ $_tmp = $this->global->uiControl->getComponent("signUpForm"); **
44: if ($_tmp instanceof Nette\Application\UI\IRenderable) $_tmp->redrawControl(null, false);
45: $_tmp->render();
46: ?><p><a href="<?php echo LR\Filters::escapeHtmlAttr($this->global->uiControl->link("in")) ?>">Already have an account? Log in.</a></p>
Editoval XpresS (25. 2. 2018 15:34)
- Ondřej Kubíček
- Člen | 494
@steelbull ten callback v create samozřejmě může mít
@XpresS a co ti to napíše přesně za chybu? tady ten jednoduchý příklad musí fungovat, nevidím tam na první pohled nic špatně
- steelbull
- Člen | 241
Je tam viac vecí, ktoré by bolo potrebné upraviť. Aby Ti Di fungoval, musíš vytvoriť továrničku. V config.neon si ju musíš zaregistrovať a potom v presenteri pridať inject, ako Ti napísal Ondrej.
A potom môžeš upraviť formulár podľa môjho:
https://forum.nette.org/…vo-formulari
Napr. vo …formSucceded nemusíš posielať values, stačí form. Values získaš z form->getValues();
- XpresS
- Člen | 4
@steelbull Zaregistroval som to dajako takto:
services:
latte.latteFactory:
setup:
- setAutoRefresh(true)
- App\Model\UserManager
- App\Forms\FormFactory
- App\Forms\SignUpFormFactory
router: App\RouterFactory::createRouter
a pravda
$values = $form->getValues();
** @OndřejKubíček **
No ako píše mi to:
Component with name ‚signUpForm‘ does not exist, did you mean
‚signInForm‘?
Myslel / myslím, si že tréba registrovať ale neviem ako a ani kde..
- steelbull
- Člen | 241
OK, zaregistroval si to spravne, problem je, ze si nevytvoril komponent.
Takze:
v presenteri pridaj property aj s commentom:
/** @var \App\Forms\ISignUpFormFactory @inject */
public $SignUpFormFactory
Uprav metodu:
protected function createComponentSignUpForm()
{
return $this->SignUpFormFactory->create();
}
A v komponente zmen nazov triedy z class SignUpFormFactory na SignUpForm
A v komponente za triedou vytvor tovarnicku aj s commentom
interface ISignUpFormFactory
{
/**
* create method.
* @return SignUpForm
*/
public function create();
}
A v config.neon zmen na:
- App\Forms\SignUpFormFactory
A to je vsetko.
XpresS napsal(a):
@steelbull Zaregistroval som to dajako takto:
services: latte.latteFactory: setup: - setAutoRefresh(true) - App\Model\UserManager - App\Forms\FormFactory - App\Forms\SignUpFormFactory router: App\RouterFactory::createRouter
a pravda
$values = $form->getValues();** @OndřejKubíček **
No ako píše mi to:
Component with name ‚signUpForm‘ does not exist, did you mean ‚signInForm‘?
Myslel / myslím, si že tréba registrovať ale neviem ako a ani kde..
Editoval steelbull (25. 2. 2018 16:52)
- steelbull
- Člen | 241
Chapem. Urob to, co som Ti napisal a pozri na ten moj formular. Uprav to podla neho.
V komponente musis mat triedu SignUpForm a tovarnicku ISignUpFormFactory
V neone musis mat – App\Forms\ISignUpFormFactory
V presenteri musis mat
/** @var \App\Forms\ISignUpFormFactory @inject */
public $SignUpFormFactory
a musis tam mat metodu
protected function createComponentSignUpForm()
{
return $this->SignUpFormFactory->create();
}
a v latte musis mat:
{component signUpForm}
To je vsetko