Elegantní kód v Nette 3 dotazy na guru
- frances
- Člen | 24
Zdravím rád bych se nette guru zeptal na 3 věci ohledně vývoje v Nette. Cílem je tvorba pěkného, přehledného, elegantního a zabezpečeného kódu:
- pomocí quickstartu: https://doc.nette.org/cs/quickstart jsem si vytvořil různé modely, ale v presenterech je taková nepěkná věc a to manipulace s DB to bych raději viděl pravě v těch modelech. Dotaz tedy zní jak využít stávající modely a obohatit je tak aby se nad nimi dali volat dotazy nad DB, to znamená jak dovnitř dostat možnost například getTaskList: $this->context->createTasklists()->order(‚title ASC‘);, ten context…?
- zabezpeceni aplikace, mam aplikaci kde jsou casti dostupne pouze pro prihlasene uzivatele a nektere pouze pro admina, v sablonach se to osetri jednoduse podminkou, v presenteru zase podminkou a redirectem. Ma se to resit take jeste na urovni modelu, vyhazovanim vyjimek? Pripadne jak nejak elegantne zabezpecovat casti presenteru aby to bylo prehledne, da se napriklad ve startup definovat ktere casti funkci presenteru jsou nepristupne pro prihlasene, neprihlasene nebo ruzne role? Jak tyto veci resite vy?
- administrace pomoci modulu – jak resite administraci aplikace tak aby to bylo pekne prehledne a nebastlil jsem kod frontendu i backendu dos tejneho presenteru a sablony? Mate nejake tipy nebo linky na diskuze kde je rozvedeno jak pomoci modulu v nette udelat krasne prehlednou strukturu pro frontend i backend?
Diky budu rad za vase tipy a nazory. Chci aby psani melo rad a peknou strukturu a chci to vzit z gruntu:)
- Martin Mates
- Člen | 179
- Měl jsem podobný problém a teď to řeším tak, že mám třídu
BaseModel, od které dědí všechny ostatní modely a ta si vezme context
z prostředí.
$this->context = \Nette\Environment::getContext();
Tuším ale, že to není úplně správně co se týče návrhového vzoru. - Co se týče toho, co může a nemůže dělat přihlášený uživatel. Je
dobré mít včechny akce, které smí udělat jen přihlášený uživatel,
v presenterech, které si to přihlášení kontrolují v metodě startup nebo
dědí od presenteru, co to kotroluje. Pokud jde o uživatelské role zaměř
se na ACL a Autorizátor. Nastuduj https://doc.nette.org/…thentication.
Budeš tam pak mít podmínky
isInRole('admin')
,isAllowed
apod. - Tady moc nerozumím otázce. Pokud už znáš moduly, tak budeš mít aplikaci přehledně rozdělenou do 2 modulů Frontend a Backend. O modulech máš něco tady: https://doc.nette.org/…n/presenters
- ViPEr*CZ*
- Člen | 822
- To co píše „Martin Mates“ o $this->context = \Nette\Environment::getContext(); tak na to zapomeňte! Odpověď na tu otázku v bodě jedna je jednoduchá a sice: „Dostane se to tam přes DI“. A když budu konkrétní, pak si jednoduše přes konstruktor modelu předáte objekt Nette\Database\Connection. Pokud si pak onen model zaregistrujete jako službu v config.neon, pak se Vám tam vztříkne instance na ten objekt přes tzv. autowiring a nemusíte se oni starat. Nebo si můžete v config.neon zaregistrovat továrničku a objekt databáze se Vám tam taky automaticky vztříkne.
Ostatní body přesně podle dokumentace co radí „Martin Mates“.
- frances
- Člen | 24
Díky za rady k tomu co pise ViPErCZ ale moc nechapu jak predat sam
sobe tuto hodnotu. V quickstartu je pripad ze mam model users ktery je
standardni faktorka a sluzbu authenticator ktery pouziva jako parametr users a
oba jsou to modely.
Ale dejte tomu ze mam model registrovan jako faktorku cms a zadnou dalsi sluzbu,
model cms ma strukturu jako vsechny faktorky:
class Cms extends Selection
{
public function __construct(Connection $connection)
{
parent::__construct('cms', $connection);
}
}
Ja mu chci ale pridat dalsi metody insertCms, deleteCms, apod…, ale podle vyse uvedeneho co pisete mi to nedava smysl, to bych musel vytvorit novy model treba CmsModel a do nej prez kontruktor predat jako sluzbu faktorku Cms kontext? Neni to blbost? Neda se rovnou z model Cms jednoduseji a elegantnejsi dostat primo ten context? Takto mi prave dava smysl to reseni od Martina i kdyz to asi neni uplne koser.
Budu rad za trosku podrobnejsi vysvetleni protoze mi to porad nedava smysl. Diky
- ViPEr*CZ*
- Člen | 822
No máte toto dejme tomu:
class Cms extends Selection
{
public function __construct(Connection $connection)
{
parent::__construct('cms', $connection);
}
}
Příliš nechápu v čem je problém udělat toto:
class Cms extends Selection
{
public function __construct(Connection $connection)
{
parent::__construct('cms', $connection);
}
public function insertCms($data)
{
...;
}
}
V presenteru pak voláte zaregistrovanou továrničku v konfigu například takto:
$cmsObj = $this->context->createCmsObj();
$cmsObj->insertCms(...);
- frances
- Člen | 24
Jiste presne takto to mam a chci to pouzivat. Jenze v tom cms neni ten databazovi objekt nad kterym mam zavolat insert do db. toto preci vyuzit nemuzu:
public function insertCms($values){
$this->context->createCms()->where('id', $values->id)->update(array(
'nadpis' => $values->nadpis,
'text' => $values->text
));
}
Celou dobu mi jde o to jak dostat do te funkce insertCms ten Cms objekt, ten kontext tu tovarnicku abych nad ni mohl zavolat insert, pres parametr predam data ale nejde mi do hlavy ze bych pokazde predaval i context->createCms()…
- ViPEr*CZ*
- Člen | 822
No v tom objektu už to máš… zavoláš to pak takhle:
class Cms extends Selection
{
public function __construct(Connection $connection)
{
parent::__construct('cms', $connection);
}
public function insertCms($values){
$this->where('id', $values->id)->update(array(
'nadpis' => $values->nadpis,
'text' => $values->text
));
}
}