Opět Call to undefined method

Dino
Člen | 7
+
0
-

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
+
+2
-

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
+
0
-

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
+
+1
-

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
+
0
-

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
+
+1
-

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
+
0
-

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
+
+1
-

@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š.