Persistentní parametr pouze pro určitou action

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Tomáš Votruba
Moderator | 1114
+
0
-
  1. Je možnost nastvit parametr persistentně pouze pro učitou action (např. edit)?
  2. Případně pokud bych chtěl pro více presenterů, nějak vhodně definovat v BasePresenteru?
Majkl578
Moderator | 1364
+
0
-
  1. – 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.
  2. – Ano, persistentní parametry napříč presentery fungují, podmínkou je, že persistentní parametr je definován ve společném předkovi.
Patrik Votoček
Člen | 2221
+
0
-

1. imho lepší updavit / přetížit PresenterComponent::getPersistentParams

Tomáš Votruba
Moderator | 1114
+
0
-

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

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.