Metoda GetUser() a \Nette\Object

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

Dobrý den vytvořil jsem třídu, kterou jsem nezval Container. Chci jednoduše zavolat metodu getUser. Dědím z \Nette\Object, tak jsem si myslel, že by to neměl být problém. Zkoušel jsem ještě use Nette\Security\User; ale to nepomáhá. V čem je problém?

<?php

<?php

namespace App\Presenters;

class Container extends \Nette\Object  {

    private $database;
    public function __construct(\Nette\Database\Context $database)
    {
        $this->database = $database;
    }

    public function overeniPristupu(){
    $user = $this->getUser();
    }
}

chyba
Nette\MemberAccessException
Call to undefined method App\Presenters\Container::getUser()

Editoval Tymikes (20. 3. 2016 14:00)

Šaman
Člen | 2666
+
+3
-

Kde jsi přišel na to, že Nette\Object má metodu getUser()? Tu má jen presenter.
Tady máš popis toho, co dělá Nette\Object v češtině.

Editoval Šaman (20. 3. 2016 15:07)

David Matějka
Moderator | 6445
+
+1
-

usera si tam predej pres konstruktor pomoci DI: https://doc.nette.org/…dependencies

Tymikes
Člen | 63
+
0
-

Jojo, díky, teď na to koukám, že to má jen presenter. Jsem se asi nějak špatně koukl. Jop, kdyžtak ho tam přidám. Spíše by mě teď zajímalo, pokud často používám v presenteru promenou $user = $this->getUser() a nechci to psát v každé funkci nebo to zase volat jinou funkcí. Jak to napsat do BasePresenteru?

ViPEr*CZ*
Člen | 818
+
0
-

Záleží jak to používáte? Teoreticky to lze použít třeba v beforeRender nebo startup metodě a tam si udělat nějakou logiku. Také lze používat rovnou magické $this->user. Nebo třeba i opožděně v šabloně, kde je dostupná proměnná user. Těžko říci takto jak to chcete vlastně použít jaká by měla být myšlenka to dostat do abstraktní třídy tak, aby jste si ušetřil práci v potomcích této abstraktní třídy.

Tymikes
Člen | 63
+
0
-

$this->user zní hodně fajn :) to mě nenapadlo. Děkuji všem :)
//Ale nefunguje mi jak bych potřeboval, nevrací mi samotné ID :/

Editoval Tymikes (20. 3. 2016 17:20)

ViPEr*CZ*
Člen | 818
+
0
-

No zavolá to magickej getter. Ale osobně mám raději klasickej getUser(), protože mi ho napovídá IDE. :-)

Tymikes
Člen | 63
+
0
-

Snad mi rozumíš, jediným smyslem teď je abych nepsal:

$userID = $this->user->id;
$userID = $this->getUser()->id;
$userID = $user->getIdentity()->id;

apod. ale pouze hodit to nějak hezky do proměnné dostupné z presenterů, momentálně nevím, jakým způsobem to udělat.

Editoval Tymikes (20. 3. 2016 17:31)

ViPEr*CZ*
Člen | 818
+
0
-

No tak si třeba v BasePresenteru udělej aliasy. Pro inspiraci >

abstract class BasePresenter extends Presenter {
	protected $userID;

	public function startup() {
		$this->userID = $this->user->id;
	}
}

Respektive na to co se ptáš, když to zobecním je to, jak si udělat proměnnou, která se inicializuje hned na startu (metoda Presenteru startup… viz dokumnetace) a má viditelnost v potomcích.

Tymikes
Člen | 63
+
0
-

Tohle jsem přesně zkoušel už, funguje mi to takto.

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    protected $userID;

    public function startup() {
        parent::startup();
        $this->userID = $this->user->id;
    }

}

Ale použití je úplně stejné jako výše s user. Tak to nechám, asi chci nějakou kravinu. :)

Šaman
Člen | 2666
+
+1
-

Tymikes napsal(a):

Snad mi rozumíš, jediným smyslem teď je abych nepsal:

$userID = $this->user->id;
$userID = $this->getUser()->id;
$userID = $user->getIdentity()->id;

apod. ale pouze hodit to nějak hezky do proměnné dostupné z presenterů, momentálně nevím, jakým způsobem to udělat.

Z vlastní zkušenosti už se různým zkratkám vyhýbám. Člověk si pak zvykne a má problém na jiných projektech, navíc skoro zapomene jak to vlastně v Nette je. $this->user->id je poměrně rychlé a dělat si proměnnou čistě pro $this->userId mi připadá zbytečné. Většinou stejně předávám celý objekt User (třeba pro potřeby autorizace).

Samozřejmě výjimky potvrzují pravidlo, u mě jsou to zkratky barDump() a fireLog(). Takže to neber doslova, ale rozhodně se zamysli, jestli užitečnost nějaké zkratky převýší případný WTF efekt, až někde třeba nebudeš dědit od svého BasePresenteru a najednou nebudou zažité postupy fungovat.

Editoval Šaman (20. 3. 2016 18:31)

Šaman
Člen | 2666
+
0
-

Tymikes napsal(a):

Tohle jsem přesně zkoušel už, funguje mi to takto.

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    protected $userID;

    public function startup() {
        parent::startup();
        $this->userID = $this->user->id;
    }

}

Ale použití je úplně stejné jako výše s user. Tak to nechám, asi chci nějakou kravinu. :)

Zdá se mi, že se ještě úplně nekamarádíš s OOP. Jestli nechceš na začátku to $this->, tak buď musíš obejít objekty (mít to někde superglobálně, definované třeba v bootstrapu – FUJ), nebo si to můžeš v konkrétní metodě vytáhnout do lokální proměnné. To je celkem běžné

<?php
# jsme v presenteru
public function foo()
{
	$user = $this->user;
	# ve zbytku metody už pracuji jen s $user
	# ale mimo ni už ne
}
?>

Editoval Šaman (20. 3. 2016 21:50)

Tymikes
Člen | 63
+
0
-

Jojo takto to používám, mě to pak došlo, že bez $this→ nazačátku to asi jen tak nepůjde udělat.
Za cca ty tři týdny už jsem rád, že jsem pochopil plno věcí, ale ještě toho hodně zbývá :D

Editoval Tymikes (20. 3. 2016 18:40)

ViPEr*CZ*
Člen | 818
+
0
-

Jo jo vím přesně o čem mluvíš. Takhle jsem kdysi jel ze školení od Davida :-)
V konkrétní metodě vytáhnout do lokální proměnné jak píše Šaman je to naprosto běžné… viz třeba:

public function renderDefault() {
	$template = $this->getTemplate();
	$templete->title = "";
	$template->keywords ...
	$template->...

	$template->render();
}

abych měl this jen 1×. ;-)