Opět Call to undefined method
- Dino
- Člen | 7
Dobrý den, omlouvám se, ale už trpím slepotou.
AdminPresenter nezná createUser.
AdminPresenter.php
use Nette;
use App\Model\UserOperation; //vloženo ručně i když je přímo v \App\Model\
....
public function signUpFormSuccess(Nette\Application\UI\Form $form)
{
$values = $form->getValues();
$count = $this->createUser($values->name, $values->email, $values->password, $values->passwordConfirm);
$this->redirect('signIn');
}
UserOperation.php
<?php declare(strict_types=1);
namespace App\Model;
use App\Model\Service\UserService;
class UserOperation
{
public function __construct(
private \App\Model\Service\UserService $userService,
private \Nette\Security\Passwords $password,
)
{
}
public function createUser(string $name, string $email, string $password, string $passwordConfirm): int
{
return $this->insertUser($name, $email, $password);
}
}
Prostředí Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
Info z Tracy
Name Autowired Service Tags
01 yes Nette\Application\Routers\RouteList
02 yes Authenticator
userService: App\Model\Service\UserService
database: Nette\Database\Explorer
password: Nette\Security\Passwords
algo: '2y'
options: array (0)
03 yes App\Model\UserOperation
04 yes App\Model\Service\UserService
database: Nette\Database\Explorer
connection: Nette\Database\Connection
structure: Nette\Database\Structure
conventions: Nette\Database\Conventions\DiscoveredConventions
cacheStorage: Nette\Caching\Storages\FileStorage
Děkuji
Editoval Dino (13. 1. 8:55)
- dms
- Člen | 87
Fuknce createUser je v objektu UserOperation, ale pak jí voláš v objektu AdminPresenter. Tak jasně že nebude fungovat. Chybí ti tam v tom presenteru něco jako
$count = $this->userOperation->createUser($values->name, $values->email, $values->password, $values->passwordConfirm);
a musíš tu službu userOperation do presenteru nějak dostat, ideálně přes dependency injection viz dokumentace
- Dino
- Člen | 7
dms napsal(a):
Fuknce createUser je v objektu UserOperation, ale pak jí voláš v objektu AdminPresenter. Tak jasně že nebude fungovat. Chybí ti tam v tom presenteru něco jako
$count = $this->userOperation->createUser($values->name, $values->email, $values->password, $values->passwordConfirm);
a musíš tu službu userOperation do presenteru nějak dostat, ideálně přes dependency injection viz dokumentace
Děkuji, to jsem tam měl původně. Byly tam i další chyby a nevhodným způsobem pokus-omyl jsem si tam, udělal další botu.
Ale i tak mi to stále nejde – chyba Cannot read an undeclared property
protected function createComponentSignUpForm(): Nette\Application\UI\Form
{
$form = new Nette\Application\UI\Form();
$form->addText('name', 'Jméno');
$form->addEmail('email', 'Email');
$form->addPassword('password', 'Password');
$form->addPassword('passwordConfirm', 'PasswordConfirm');
$form->addSubmit('send', 'Sign Up');
$form->onSuccess[] = [$this, 'SignUpFormSuccess'];
return $form;
}
Editoval Dino (13. 1. 10:35)
- nightfish
- Člen | 474
Dino napsal(a):
Ale i tak mi to stále nejde – chyba Cannot read an undeclared property
Pravděpodobně to máš polámaný. Nemám pocit, že by se ta chybová
hláška týkala metody createComponentSignUpForm()
, jejíž kód
jsi poslal. Takže pokud s tím chceš poradit nějak víc, bude potřeba víc
kontextu (nejlépe celé znění chybové hlášky, včetně uvedení čísla
řádku, na kterém se vyskytla + kód z daného řádku + pár řádků před
i po).
A nebo ještě lépe – na místě, kde ti to přístup na „undeclared property“ hlásí, si vypiš hodnotu (proměnnou/výsledek volání funkce atd.), na které k té property přistupuješ – třeba ti to napoví, v čem by mohl být problém.
- Dino
- Člen | 7
Děkuji.
Schválně jsem to předělal do nové třídy UserFacade.php a stále nic.
Nechtěl jsem kopírovat své vlastní překlepy.
Chyba na řádku 58 Nette\MemberAccessException
Cannot read an undeclared property
App\Presenters\AdminPresenter::$UserFacade.
...\xampp\htdocs\quiz\app\Presenters\AdminPresenter.php:58
48: $form->addPassword('passwordConfirm', 'PasswordConfirm');
49: $form->addSubmit('send', 'Sign Up');
50: $form->onSuccess[] = [$this, 'SignUpFormSuccess'];
51: return $form;
52: }
53:
54: public function signUpFormSuccess(Nette\Application\UI\Form $form)
55: {
56: $values = $form->getValues();
57:
58: $count = $this->UserFacade->createUser($values->name, $values->email, $values->password, $values->passwordConfirm);
59: // var_dump($values);
60:
61:
62: /* try {
$name
'UserFacade'
UserFacede.php
<?php declare(strict_types=1);
namespace App\Model;
use App\Model\Service\UserService;
class UserFacade
{
public function __construct(
private \App\Model\Service\UserService $userService,
private \Nette\Security\Passwords $password,
)
{
}
public function createUser(string $name, string $email, string $password, string $passwordConfirm): int
{
return $this->insertUser($name, $email, $password);
}
}
service.neon
services:
- App\Router\RouterFactory::createRouter
- Authenticator
- App\Model\UserFacade
- App\Model\Service\UserService
Děkuji
- nightfish
- Člen | 474
Dino napsal(a):
Schválně jsem to předělal do nové třídy UserFacade.php a stále nic.
Poučení pro příště: Když přesouváš chybný kód mezi třídami, tak to většinou nevyřeší příčinu problému.
Nechtěl jsem kopírovat své vlastní překlepy.
Nikdo z nás tu nemá funkční křišťálovou kouli, takže abychom komukoliv mohli poradit, potřebujeme k tomu dostatek kontextu (celá znění chybových hlášek, relevantní kusy kódu atd.). To, co jsi poslal ve svém posledním příspěvku, už je mnohem lepší.
Chyba na řádku 58 Nette\MemberAccessException
Cannot read an undeclared property App\Presenters\AdminPresenter::$UserFacade.
Což znamená, že na řádku 58 AdminPresenteru se pokoušíš přistupovat
k property $UserFacade
, která neexistuje.
Pokud by existovala, tak by zřejmě byla uvedena někde na začátku presenteru v podobě:
#[\Nette\DI\Attributes\Inject]
public \App\Model\UserFacade $UserFacade;
nebo
/** @inject */
public \App\Model\UserFacade $UserFacade;
nebo
public function __construct(private \App\Model\UserFacade $UserFacade) {...}
Máš něco takového v AdminPresenteru
(nebo nějakém
předkovi AdminPresenteru
)?
Předpokládám, že by ti mohlo pomoct i přečíst si dokumentaci
k předávání závislostí v Nette.
- Dino
- Člen | 7
AdminPresenter.php a jeho začátek. Nic takového tam nemám.
Začátek Autheticator.php
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use App\Model\UserFacade;
final class AdminPresenter extends Nette\Application\UI\Presenter
{
public function startup()
{
parent::startup();
if ($this->getUser()->isLoggedIn() === false && $this->getAction() !== 'signIn' && $this->getAction() !== 'signUp' && $this->getAction() !== 'forgotPassword') {
$this->flashMessage('Tato sekce není přístupná bez přihlášení.', 'primary');
$this->redirect('signIn');
}
}
Dělal jsem to podle Authenticator.php, který mi fungoval. Ale ten to dědí.
<?php declare(strict_types=1);
use Nette\Security\IIdentity;
class Authenticator implements \Nette\Security\Authenticator
{
public function __construct(
// private \Nette\Database\Explorer $database,
private \App\Model\Service\UserService $userService,
private \Nette\Security\Passwords $password,
)
{
}
public function authenticate(string $username, string $password): \Nette\Security\IIdentity
{
Díky
- nightfish
- Člen | 474
@Dino Ok. Takže situace je taková, že v AdminPresenteru
potřebuješ použít službu UserFacade
. Jinými slovy „služba
UserFacade
je závislostí AdminPresenteru“. Ukázky kódu,
kterými si do presenteru můžeš závislosti předat, jsem ti poslal
v předchozím komentáři. Stejně tak jsem ti poslal odkaz do dokumentace,
kde je to podrobně vysvětlené.
…takže si ten článek v dokumentaci přečti, zkus jej aplikovat na svůj problém a kdyby se nedařilo, tak napiš.