Deklarace persistentních parametrů a komponent bez anotací

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8227
+
0
-

Odedneška lze deklarovat persistentní parametry a komponenty bez použití anotací. Slouží k tomu dvě nové statické metody getPersistentParams() a getPersistentComponents(). Každá vrací pole, jehož klíče nebo hodnoty tvoří jména parametrů resp. komponent.

Protože statické metody v PHP < 5.3 jsou opruz, dostávají tyto metody jako parametr jméno třídy. Také není potřeba, aby vracely seznam parametrů nebo komponent svých předků.

Příklad:

// pomocí anotací:
class FifteenControl extends /*Nette\Application\*/Control
{
	/** @persistent */
	public $order;

	/** @persistent */
	public $round = 0;
}

// pomocí metody getPersistentParams
class FifteenControl extends /*Nette\Application\*/Control
{
	public $order;

	public $round = 0;

	public static function getPersistentParams()
	{
		return array('order', 'round');
	}
}

A persistentní komponenty:

// pomocí anotací:
/**
 * @persistent(game)
 */
class DefaultPresenter extends /*Nette\Application\*/Presenter
{
	public function actionDefault()
	{
		$game = new FifteenControl($this, 'game');
		...


// pomocí metody getPersistentComponents
class DefaultPresenter extends /*Nette\Application\*/Presenter
{
	public static function getPersistentComponents()
	{
		return array('game');
	}

	public function actionDefault()
	{
		$game = new FifteenControl($this, 'game');
		...

Vyšší prioritu má funkce nad anotacemi. Přesněji řečeno, výchozí implementace každé z funkcí vrací pole detekované z anotací. Tím, že ji přepíšete, tak vlastně zrušíte toto chování a anotace určujete manuálně.

Honza Marek
Člen | 1664
+
0
-

Super… Až zase potkám zlý hosting, tak mi to ušetří spoustu nervů.

PetrP
Člen | 587
+
0
-

Davide jsi skutečně blesk. Jak se ale budou řešit další meta informace v daleké budoucnosti (doufám že neprozrazuju nějaké tajemství). Myslel jsem že přidáš jednotný způsob přidání všech takovýchto informací. Nebo chceš jít cestou kdy pro každej typ budeš mít takhle vlastní metodu.

Mimochodem je možný způsoby kombinovat? A jak? Nebude to dělat někde nějaké problémy?

Wosonj
Člen | 36
+
0
-

Super!!! Díky moc!

Tenhle příspěvek má za účel přidat do threadu klíčové slovo eAccelerator, aby byl na eAccelerator vyhledatelný a nikdo se už neztrapnil podobně jako já včera

PetrP
Člen | 587
+
0
-

Na poslední sobotě se mluvilo i o bCompileru, že v něm nefungujou perzistentní parametry. Takže přidam pro vyhledávání i bCompiler. ;]

David Grudl
Nette Core | 8227
+
0
-

PetrP napsal(a):

Davide jsi skutečně blesk. Jak se ale budou řešit další meta informace v daleké budoucnosti (doufám že neprozrazuju nějaké tajemství). Myslel jsem že přidáš jednotný způsob přidání všech takovýchto informací. Nebo chceš jít cestou kdy pro každej typ budeš mít takhle vlastní metodu.

Současné řešení je asi nejjednodušší a nejsrozumitelnější pro uživatele. V podstatě i nějak takto by mohl vypadat „jednotný“ způsob. To ukáže čas.

Mimochodem je možný způsoby kombinovat? A jak? Nebude to dělat někde nějaké problémy?

Ano, obojí lze libovolně kombinovat.

David Grudl
Nette Core | 8227
+
0
-

Wosonj napsal(a):

Super!!! Díky moc!

Tenhle příspěvek má za účel přidat do threadu klíčové slovo eAccelerator, aby byl na eAccelerator vyhledatelný a nikdo se už neztrapnil podobně jako já včera

Neztrapnil, jen jsi demonstroval, že v Nette se požadavky řeší o 13 hodin dřív, než se vznesou :-)))

neo.taa
Člen | 14
+
0
-

Jooooooooo super, taky jsem tohle půldne řešil a marně :-( No ještě že existuje tohle forum.

Jakub Šulák
Člen | 222
+
0
-

Tak jsem asi špatně Davida pochopil. Píše, že řešení lze kombinovat, což ale není tak úplně pravda – kombinovat to jde jen za cenu přetížení metody getPersistentParams().

Myslel jsem si, že to bude fungovat trochu jinak – budu mít nadefinované persistení proměnné přes anotace a budu moci některé proměnné definovat navíc přes tuto metodu.

Nešlo by přidat metodu:
addPersistentParams($arrayOfParams)

která by vložila další parametry?

Jedná se mi o to, když člověk potřebuje programově rozhodnout, zda bude/nebude proměnná persistentní – nemohu to zapsat logicky do anotace. Ale pokud si chci (z historických důvodů, nebo kvůli přehlednosti) nechat jiné deklarace v anotacích, nemusel bych přetěžovat metodu getPersistentParams().

Navíc v okamžiku, kdy se v ní něco změní, tak to zapomene člověk upravit, jedině v ní volat natvrdo PresenterComponent::getPersistentParams().

morousej
Člen | 18
+
0
-
<?php
private static $paramsToAdd = array();

public static function addPersistantParams($arrayOfParams)
{
	self::$paramsToAdd = array_merge(self::$paramsToAdd, $arrayOfParams);
}

public static function getPersistantParams($className)
{
	return array_merge(parent::getPersistantParams($className), self::$paramsToAdd);
}
?>

Editoval morousej (10. 6. 2009 18:18)

Jakub Šulák
Člen | 222
+
0
-

nevím proč, ale předtím mi to psalo chybu když jsem volal parent:: – hmmm.
ale díky – takto to je bez problému.

DocX
Člen | 154
+
0
-

Měl bych k této problematice ještě jeden dotaz. Jde nějak programově určit defaultní hodnotu parametru? Já jsem zkusil upravit PresenterHelper::getPersistentParams :

<?php
	public static function getPersistentParams($class)
	{
...
			foreach (call_user_func(array($class, 'getPersistentParams'), $class) as $name => $meta) {
				if (is_string($name)) $default[$name] = $meta; else if (is_string($meta)) $name = $meta;
				$params[$name] = array(
					'def' => $defaults[$name],
					'since' => $class,
				);
			}
...
	}
?>

a potom použít GetPersistentParams ve vlastní třídě následovně:

<?php
class MyClass extends Presenter

	public $lang;

	public static function getPersistentParams()
	{
		return array('lang' => Environment::getConfig('langs.default', 'en'));
	}
?>

ale tvorba odkazů se stále chová jako když parametr nema výchozí hodnotu. (pokud by v konfiguraci bylo „cs“ tak i při url ?lang=cs se $this->canonicalize() nepřesměruje na url bez lang). Pokud výchozí přiřazení připíšu, chová se jak má. Takže jde spíš o to, zjistit, podle čeho to adresy s persistentnímy parametry zkracuje, když to není výstup funkce GetPersistentParams()

PetrP
Člen | 587
+
0
-

A normální „přiřazení“ defaultní hodnoty nefunguje?

public $lang = 'cs';

případně si jí nastavovat v __construct ale to není moc pěkné no.

DocX
Člen | 154
+
0
-

PetrP napsal(a):

A normální „přiřazení“ defaultní hodnoty nefunguje?

Ano to funguje. Já bych ale potřeboval tuto defaultní hodnotu určit až v runtime. Protože se podle ní potom zkracuje url, když je hodnota parametru stejná jako jeho defaultní hodnota.

Je mi proto divné, že i když jsem upravil metodu PresenterHelper::getPersistentParams() tak, aby to jako defaultni hodnotu považovalo tu, kterou předám mojí override metodou getPersistentParams, stále to někde jinde pozná ještě přímo z definice té proměnné v kódu třídy. Nemohu ale nalézt kde se tak děje :(