Persistentní parametr pouze pro určitou action
- Tomáš Votruba
- Moderator | 1114
- Je možnost nastvit parametr persistentně pouze pro učitou action (např. edit)?
- Případně pokud bych chtěl pro více presenterů, nějak vhodně definovat v BasePresenteru?
- Majkl578
- Moderator | 1364
- – Ne, teoreticky si to můžeš doimplementovat, např. v load/saveState
kontrolovat podle anotace (
/** @persistent @for(foo, bar) */
) a na základě toho nehodící se nulovat. - – Ano, persistentní parametry napříč presentery fungují, podmínkou je, že persistentní parametr je definován ve společném předkovi.
- Tomáš Votruba
- Moderator | 1114
Díky oběma za podněty.
Use case (kombinace presenter / view zatím neřeším, prioritu má Presenter).
/** @persistent @forPresenter(DiscussionPresenter, ItemPresenter) @forView(cafe, betting, default) */
public $uid;
@Majkl578: Tak nějak by to šlo. Navrhuješ tedy
přežít loadState/saveState
v Presenteru? Mám v ní přístup
k jejich anotacím?
Toto mi, zdá se, funguje dle očekávání. Prosím zhodnotit.
public function loadState(array $params)
{
parent::loadState($params);
$this->params = $this->filterCustomPersistentParams($this->params);
}
public function saveState(array & $params, $reflection = NULL)
{
parent::saveState($params, $reflection);
$params = $this->filterCustomPersistentParams($params);
}
/**
* Check persistent for* annotations
* @param array
* @return array
*/
private function filterCustomPersistentParams($params)
{
$reflection = $this->getReflection();
$presenter = $reflection->name;
$view = $this->view;
foreach ($reflection->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) {
if ($rp->hasAnnotation("persistent")) {
if ($rp->hasAnnotation("forPresenter")) {
$allowedPresenters = (array) $rp->getAnnotation("forPresenter");
if (!in_array($presenter, $allowedPresenters)) {
unset($params[$rp->getName()]);
}
} elseif ($rp->hasAnnotation("forView")) {
$allowedViews = (array) $rp->getAnnotation("forView");
if (!in_array($view, $allowedViews)) {
unset($params[$rp->getName()]);
}
}
}
}
return $params;
}
@Patrik Votoček: Zde bych si dokázal poradit s presenterem. Jak ale získat v této statické fci view?
Zatím se mi podařilo vytvořit něco takového (ještě to
@forView
):
/**
* Custom persistent params
*/
public static function getPersistentParams()
{
$rc = new \Nette\Reflection\ClassType(get_called_class());
$params = array();
foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) {
if (!$rp->isStatic() && $rp->hasAnnotation("persistent")) {
if ($rp->hasAnnotation("forPresenter")) {
$allowedPresenters = (array) $rp->getAnnotation("forPresenter");
if (in_array($rc->getName(), $allowedPresenters)) {
$params[] = $rp->getName();
}
} else {
$params[] = $rp->getName();
}
}
}
return $params;
}
EDIT: Zjistil jsem, že při získání requestu je použito
getPersistentParams
v PresenterComponentReflection,
kde probíhá jakési dvojité ověření. Musel bych tedy
getPresistentParams
přepsat dvakrát (předpokládám).
Editoval Schmutzka (19. 9. 2012 2:51)
- Filip Procházka
- Moderator | 4668
Možná bych se zamyslel nad tím, jestli nedává větší smysl mít ten persistentní parametr v nějaké komponentě a ten view vyčlenit.