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

Ahoj, zkouším již delší dobu vytvořit jednu aplikaci, vše se mi daří a na to že využívám Nette cca 14 dní, se mi velice líbí a vše funguje jak má, kompletně celá aplikace, ale…

Aby při dalším psaní nedocházelo k zbytečnému opakování kodu, chtěl bych si rozšířit třídu User o nějaké metody, tedy využít původní třídu, ale extendovat jí o další metody, ale vůbec nevím jak na to.

Zkoušel jsem projet forum a vždy jsem odpověd našel, ale nyní ne a nepřišel jsem vůbec jak na to. Zkoušel jsem různé fígle přes registraci třídy v config.neon přes service: user: <třída>, ale taky bez úspěchu.

Potřeboval bych tedy přesný návod, co je potřeba dodržet při extendování třídy Nette\Security\User, nikde jsem bohužel odpověd nenašel a nejsem žádný hvězdný programátor. Díky za případný rychlý brief.

Hodně zdaru! :)

PS: Dokumentace mi toho také moc nedala, prostě jsem to nepochopil, třeba budu mít štěstí nyní. :)

Editoval GEpic (28. 12. 2015 23:51)

enumag
Člen | 2118
+
0
-

O co konkrétně se ji snažíš rozšířit? Ne vždy je dobrý nápad rozšiřovat existující třídu, často je lepší použít skládání.

GEpic
Člen | 566
+
0
-

Nemusím jí nutně rozšiřovat, chtěl bych pouze využívat jako doposud $this->user ale třeba s funkcí $this->user->getAvatar() nebo získávat ostatní informace o daném právě přihlášeném uživateli. Pokud existuje jiný, pohodlný způsob, budu jedině rád. Chci aby se tyto informace načetli při vytvoření instance třídy a pak údaje popřípadě měnit, jako třeba email uživatele, heslo, telefonní číslo, apod. Doposud to řeším tak, že mám v každém formuláři přímo dotaz na databázi, ale nepřijde mi to pohodlné, jelikož informace o uživateli získávám docela často na více místech, nebo je nastavuji.

Editoval GEpic (29. 12. 2015 1:22)

enumag
Člen | 2118
+
+2
-

V tom případě bych zvážil možnost ukládat tyto informace do Identity když ji vytváříš v authenticatoru.

GEpic
Člen | 566
+
0
-

Dlouho jsem se tomu nevěnoval, zatím mám jiné řešení a tvořil jsem jiné věci a seznamoval se s dalšími možnostmi .Nette…

Neměl bys nějaký jednoduchý příklad? Já stále hledám, ale asi špatně…

iNviNho
Člen | 352
+
0
-

No napadli ma 2 možnosti:

A

Vytvoriť si triedu (napr.) MyUser a v nej si vyžiadať triedu Nette\Security\User

To ti umožní používať všetko čo má táto trieda a môžeš si do nej napísať čo len chceš :)

<?php
class MyUser extends \Nette\Object {

    /**
     *
     * @var Nette\Security\User
     */
    private $user;

    public function __construct(Nette\Security\User $user) {

	$this->user= $user;

    }

	public function getUser() {
		return $this->user;
	}
}
?>

B

Naozaj extendovať túto triedu.

<?php
class User extends \Nette\Security\User {

    /** @var UserService */
    public $userService;

    public function __construct(UserService $userService, \Nette\Security\IUserStorage $storage, \Nette\Security\IAuthenticator $authenticator = NULL, \Nette\Security\IAuthorizator $authorizator = NULL) {
	parent::__construct($storage, $authenticator, $authorizator);

	$this->userService = $userService;
    }

    /**
     * Checks if logged user is in role of "admin"
     * @return bool
     */
    public function isAdmin() {
	return $this->isInRole("admin");
    }

?>

Pripomeniem, že v configu som ešte ťukol

user: App\Services\User

EDIT: Možnosť A som používal, možnosť B používam

Editoval iNviNho (5. 1. 2016 18:31)

GEpic
Člen | 566
+
0
-

Díky moc iNviNho

Tak jednoduché a mě to pořád nešlo, víc jsem nepotřeboval, jen jak to použít v konfigu a jak extendovat Usera.

Ještě jednou díky moc! :)

PS: Jen tak letmo když na to koukám.. při extendování třída user zůstane stejná, bude se volat stejně (tedy
$this->getUser(), kde getUser() mi vrátí instanci mé třídy? Pouze bude obsahovat nové funkce, které přidám apod. že?

Editoval GEpic (5. 1. 2016 20:08)

iNviNho
Člen | 352
+
0
-

GEpic napsal(a):

Díky moc iNviNho

Tak jednoduché a mě to pořád nešlo, víc jsem nepotřeboval, jen jak to použít v konfigu a jak extendovat Usera.

Ještě jednou díky moc! :)

PS: Jen tak letmo když na to koukám.. při extendování třída user zůstane stejná, bude se volat stejně (tedy
$this->getUser(), kde getUser() mi vrátí instanci mé třídy? Pouze bude obsahovat nové funkce, které přidám apod. že?

Za málo :)

Jasné :) Ak by si chcel aby metoda getUser() robila niečo iné, tak si ju iba preťažíš v novej triede. Inak ak do tej triedy nenapíšeš nič, tak vlastne tvoja trieda bude to isté čo Nette\Security\User …

Ja som si prepísal tú metodu, pretože chcem aby mi vracal entitu Usera a vždy mám aktuálne data z DB (používam Doctrine 2 ORM)

Editoval iNviNho (5. 1. 2016 21:47)

CZechBoY
Člen | 3608
+
0
-

getUser() je ale metoda UI\Presenteru a ne Security\User.

iNviNho
Člen | 352
+
0
-

Aha, môže byť :)

Ja to používam ako

<?php
$this->user->getEntity()
?>
GEpic
Člen | 566
+
0
-

Takže né:

$this->getUser();

Ale

$this->user;

Ale getUser() presenteru taktéž vrací Security\User, ne?

PS: Vyzkouším, uvidím…
PS2: Doctrine mě zajímá, mrknu na něj taky, jsem nový, sbírám co se dá… :D

Editoval GEpic (5. 1. 2016 22:16)

Aurielle
Člen | 1281
+
+1
-

->getUser() a ->user jsou ekvivalentní.

GEpic
Člen | 566
+
0
-

Aurielle napsal(a):

->getUser() a ->user jsou ekvivalentní.

Díky moc, ted už vím opravdu vše a naprosto jak se věci mají, projel jsem si i samotné Nette co vrací a potvrdil jsi mi to.

PS: Jen další dotaz, (extend už mi funguje), aby po zalogování uživatele se načetli hodnoty do proměnných z databáze, abych je nemusel při každém volání tahat znovu? Spíš, nevím přesně, jak využít událost $onLoggedIn

Co říkáte na toto řešení? Popř. jak by jste řešili get a set z / do databáze vy?

<?php

namespace App\Model;

use Nette,
    Nette\Security;


class User extends Security\User
{
    /** @var bool|mixed|Nette\Database\Table\IRow  */
    private $extUser;

    /**
     * User constructor.
     * @param Nette\Database\Context $database
     * @param Security\IUserStorage $storage
     * @param Security\IAuthenticator|NULL $authenticator
     * @param Security\IAuthorizator|NULL $authorizator
     */
    public function __construct(Nette\Database\Context $database, Security\IUserStorage $storage, Security\IAuthenticator $authenticator = NULL, Security\IAuthorizator $authorizator = NULL)
    {
        parent::__construct($storage, $authenticator, $authorizator);
        $this->extUser = $database->table('users')->where('id', $this->getId())->fetch();
    }

    /**
     * @return string
     */
    public function getUsername()
    {
        return $this->extUser->username;
    }

    /**
     * @param $username
     */
    public function setUsername($username)
    {
        $this->extUser->update(array( "username" => $username));
    }
}

Editoval GEpic (6. 1. 2016 3:04)

F.Vesely
Člen | 369
+
0
-

Pro Doctrine existuje Majkl578/nette-identity-doctrine, ktere ti hodi do Identity rovnou Entitu. Prijde mi to lepsi, nez to mit vsechno v Nette\Security\User, protoze se ti do aplikace muzou prihlasit napriklad Admin, Dealer, Customer a kazdej bude mit jina data, jak to pak nacpes vsechno do Nette\Security\User?

GEpic
Člen | 566
+
0
-

F.Vesely napsal(a):

Pro Doctrine existuje Majkl578/nette-identity-doctrine, ktere ti hodi do Identity rovnou Entitu. Prijde mi to lepsi, nez to mit vsechno v Nette\Security\User, protoze se ti do aplikace muzou prihlasit napriklad Admin, Dealer, Customer a kazdej bude mit jina data, jak to pak nacpes vsechno do Nette\Security\User?

To se mi taky moc líbí. PS abych zodpověděl tvou otázku, jde pak už o samotný návrh aplikace, kde v tomto případě to není potřeba a samozřejmě chápu že situace a data mohou být různá. Záleží pak na samotném navržení databáze. Každopádně, využíváš doctrine2nette taky?

F.Vesely
Člen | 369
+
0
-

Ano.