Z kterého presenteru a view se přišlo

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

Řeším takový problém, kdy v jednom presenteru potřebuji vědět, z jakého presenteru a view přišel požadavek. Přes nějaké parametry v URL se mi to řešit nechce. Zatím na to jdu parsováním tohoto:

<?php
  Environment::getHttpRequest()->getReferer()->path
?>

Teď by mě ale spíš zajímalo, proč se nedá moc spoléhat na hlavičku Referer. Jestli je to kvůli tomu, že se třeba dá v prohlížeči nějak potlačit nebo podvrhnout nebo jestli je k tomu jiný důvod (z pohledu Nette).

Panda
Člen | 569
+
0
-

Dá se podvrhnout a některý „hodný software“ jí dokonce z požadavků od klienta vyjme (prý „ochrana soukromí“). Co vím, tak to dělal třeba Kerio Personal Firewall.

Ondřej Mirtes
Člen | 1536
+
0
-

Z jakého důvodu to potřebuješ? Nestačilo by na to náhodou Application::storeRequest() a restoreRequest()?

radas
Člen | 221
+
0
-

Ondřej Mirtes napsal(a):

Z jakého důvodu to potřebuješ? Nestačilo by na to náhodou Application::storeRequest() a restoreRequest()?

Právě že se nepotřebuji vracet na původní stránku. Z různých presenterů se volá konkrétní action jednoho presenteru, která něco udělá a pošle hlavičky (pro stáhnutí souboru, který se vygeneruje). A právě na základě toho odkud požadavek přišel, se ta action chová. Buď vezme data z identity přihlášeného uživatele nebo je vezme z databáze atd.

Ale asi to budu muset řešit nějakým parametrem v URL.

redhead
Člen | 1313
+
0
-

A není nejlepší ve startupu BasePresenteru, udělat jednoduché vložení někam do session (proměnné $this->name a $this->action) a potom si to z ní vytáhnout??

radas
Člen | 221
+
0
-

redhead napsal(a):

A není nejlepší ve startupu BasePresenteru, udělat jednoduché vložení někam do session (proměnné $this->name a $this->action) a potom si to z ní vytáhnout??

No, možné to je, ale jak se bude aplikace chovat, když ji otevřu ve více tabech prohlížeče? Podle mě se session přepíše tou novější a když se pak vrátím zpět a přejdu z původního tabu na novou stránku, tak to nebude odpovídat skutečnosti…

Asi to nakonec udělám přes parametr v URL.

Editoval radas (5. 3. 2010 11:26)

redhead
Člen | 1313
+
0
-

Nějak by se to dalo udělat, mám pocit, že flashMessages takhle fungují i ve více oknech.. Ale nevím jaká je v tom magie.

Ale cestou URL by to šlo taky, dokonce by sis to mohl zautomatizovat přepsáním pár metod v BasePresenteru (abys to nemusel psát v každém {link} makru)

Etch
Člen | 403
+
0
-

flashMessages takhle fungují právě díky tomu, že používají GET parametr

redhead
Člen | 1313
+
0
-

pravda, na to sem zapomněl

radas
Člen | 221
+
0
-

redhead napsal(a):

Nějak by se to dalo udělat, mám pocit, že flashMessages takhle fungují i ve více oknech.. Ale nevím jaká je v tom magie.

Ale cestou URL by to šlo taky, dokonce by sis to mohl zautomatizovat přepsáním pár metod v BasePresenteru (abys to nemusel psát v každém {link} makru)

Přepsáním pár metod v BasePresenteru myslíš přesně co?

Protože aplikace používá víceméně jedinou routu <presenter>/<action>/<id [0–9]+>, tak by ještě mohlo jít pomocí druhé routy <presenter>/<action>/<id [0–9]+>/<referer [0–9]+> předávat nějaké ID pohledu, ze kterého se přišlo, klidně číslované od 1 výš. Kód v těle příslušné metody už by se podle toho ID pohledu zařídil. Tím pádem i zůstanou cool URL :-)

redhead
Člen | 1313
+
0
-

asi by to šlo i přes jednu metodu:

je to pouze nástin, nevím jesli bude fungovat:

// TOTO JE NORMÁLNÍ LINK METODA TŘÍDY PresenterComponent
public function link($destination, $args = array())
{
	if (!is_array($args)) {
		$args = func_get_args();
		array_shift($args);
	}
	try {
		return $this->getPresenter()->createRequest($this, $destination, $args, 'link');

	} catch (InvalidLinkException $e) {
		return $this->getPresenter()->handleInvalidLink($e);
	}
}

// PŘETÍŽENÍM V BASEPRESENTERU:
public function link($destination, $args = array())
{
	if (!is_array($args)) {
		$args = func_get_args();
		array_shift($args);
	}
	$id = vygenerujMiCisloActionPresenteru()	//to tvé ID, které pude do URL
	return parent::link($destination, $args + array('referer' => $id));
}

Jen potřebuješ nějak určit to ID presenteru a action jak si říkal.. Potom si dát do route ten referer a mohlo by to jet (aspoň doufám). Problém by asi byl u Controlů, kde bys to musel překrýt taky v nějaké trídě BaseControl..

Editoval redhead (5. 3. 2010 12:18)

radas
Člen | 221
+
0
-

No jo, ale když pak DG v budoucnu tělo té metody změní tak mi taky aplikace může přestat běžet. Asi by to takto šlo, ale je to velká daň za to, že se automaticky přidá parametr do URL. Přesto díky za nástin možností.

Ondřej Mirtes
Člen | 1536
+
0
-

Udělal bych to podle parametru action. Podle nějakého refereru je to chování příliš neprůhledné a do budoucna by se to špatně rozšiřovalo.

redhead
Člen | 1313
+
0
-

Tak samozřejmě, ale dalo by se to opravit. Navíc, BC breaku se v této metodě doufám nedočkáme. Ale i kdyby, nemyslím si, že by to bylo nějak razantně odlišné. Nette na tomhle způsobu staví, a to že metodě link pošleš argument navíc, by nemělo ničemu vadit. Podle mě furt lepší brát riziko, že jednou budeš muset změnit kód jedné metody, než měnit volání linku ve všech šablonách..

Jinak byli tady už větší přepisování metod, např. pro zabezpečení linků před CSRF pomocí anotací.