Anotace – nefunguji u signalu
- MelkorNemesis
- Člen | 36
Ahoj,
zkousel jsem dat anotaci /** @secured */ k signalu, ale nefunguji.
<?php
$signalMethod = $this->formatSignalMethod($this->signal);
?>
Problem:
V $this->signal (stejne tak $this->getSignal()) je:
<?php
array(2) {0 => "", 1 => "addfriend"}
?>
takze se v $signalMethod (ktera se nasledne predava dale anotacim) objevi „handleArray“.
Muze to nekdo prosim opravit? Rad bych anotace vyuzival i na signaly (zejmena v ajaxovych requestech) a nechci kvuli tomu vrtat sam do Nette. Stacilo by prehodit $signal v Nette z private na protected.
Kod od Romana Sklenare – radek 63 je chybovy
https://github.com/…resenter.php#L63
Jsem s pozdravem, Michal Sevcik
Editoval MelkorNemesis (4. 2. 2010 18:10)
- Ondřej Mirtes
- Člen | 1536
Tohle nesouvisí s Nette, nýbrž s Romanovým kódem, kde je tato chybka :)
Ale řekl bych, že ke správné funkčnosti stačí zaměnit tento řádek:
$signalMethod = $this->formatSignalMethod($this->signal);
za tento:
$signalMethod = $this->formatSignalMethod($this->signal[1]);
Takže žádné vrtání v Nette není potřeba.
Zkus to a dej vědět, jestli to funguje.
- MelkorNemesis
- Člen | 36
No to samozrejme funguje, zkousel jsem to i predtim, jen mi prijde lepsi mit v $this->signal nazev signalu a ne pole, ktere ma nevim proc prazdny prvni prvek.
- romansklenar
- Člen | 655
V nové verzi Nette byl změněz způsob práce s anotacemi, kód na githubu je už více než dva měsíce starý a je určen pro verzi Nette 0.9.2.
I přesto se mi nezdá, že by metoda getSignal
měla
vracet pole – Nette je navrhnuto tak, že Presenter umí zpracovat pouze
jeden signál, pokud se nic nezměnilo. Takže rada „použij
$this->signal[1]
protože to tak funguje“ je s prominutím
čistá blbost.
EDIT: Implementace metody getSignal není to zrovna nejšťastnější. Protože presenter může obsluhovat jen jeden signál, stálo by možná za to změnit strukturu vráceného pole, to je ale na jinou diskusi. Budeš si muset upravit získávání anotace pro handler signálu tak, aby uměla přijmout pole, tak jak napsal Ondra.
Editoval romansklenar (4. 2. 2010 19:30)
- Ola
- Člen | 385
Zkusím tuto chybu uvést na pravou míru. V Presenter.php je členská proměnná (private) $signal – je důležité, že je private. Pokud zapíšeme $object->something, za předpokladu, že $object je instance/potomek Nette\Object a $object nemá public proměnnou something. To je základ, na který navážeme: protože kód anotací je definován v potomkovi Presenter, stává se pro něj proměnná $signal nepřístupná (přístupná by byla jen kdyby byla protected). Tedy volání $this->signal v potomkovi vyvolá volání $this->getSignal() – jenomže tato metoda je v nette napsaná tak, aby vracela pole signal receiver ⇒ signal, tedy vrátí pole, což je ale v tomto případě nežádoucí.
Editoval Ola (4. 2. 2010 19:17)
- Ondřej Mirtes
- Člen | 1536
Vrací pole pro případy, kdy je v URL ?do=komponenta-signál
,
např. ?do=editForm-submit
, pak je první prvek pole
editForm
a druhý submit
.
Romane – nevím, proč říkáš, že jsem poradil blbost – o žádnou chybu v Nette nejde, jen je chybka v tvém kódu. Před pár dny jsem to zrovna řešil a na tohle taky narazil. Kromě aktualizace na nejnovější verzi anotací jsem chtěl ještě přidat podporu @secured pro submitovací metody formuláře – ale narazil jsem na nějakou bariéru, už nevím jakou.
private function checkPermissions() {
$annotation = 'secured';
$actionMethod = $this->formatActionMethod($this->action);
$signalMethod = $this->formatSignalMethod($this->signal[1]);
$renderMethod = $this->formatRenderMethod($this->view);
if ($this->getReflection()->hasAnnotation($annotation)) {
$authenticate = TRUE;
$privilege = NULL; //whole class
} elseif ($this->hasMethodAnnotation($actionMethod, $annotation) || $this->hasMethodAnnotation($renderMethod, $annotation)) {
$authenticate = TRUE;
$privilege = $renderMethod;
} elseif ($this->isSignalReceiver($this) && $this->hasMethodAnnotation($signalMethod, $annotation)) {
$authenticate = TRUE;
$privilege = $signalMethod;
} else {
$authenticate = FALSE;
}
//tady už jsem provedl trochu více úprav, nezkoumám pouze přihlášení usera, ale jestli na to má povolení v třídě Permission
$user = $this->getUser();
if ($authenticate) {
if ($user->isAuthenticated()) {
if (!$user->isAllowed($this->name, $privilege)) {
throw new BadRequestException('Permission denied', 403);
}
} else {
if ($user->getSignOutReason() === User::INACTIVITY) {
$this->flashMessage('You have been logged out due to inactivity. Please log in again.', 'error');
}
$backlink = $this->getApplication()->storeRequest();
$this->redirect('Auth:login', array('backlink' => $backlink));
}
}
}
private function hasMethodAnnotation($method, $annotation) {
return $this->getReflection()->hasMethod($method)
&& $this->getReflection()->getMethod($method)->hasAnnotation($annotation);
}
Editoval Ondřej Mirtes (4. 2. 2010 19:25)
- Ola
- Člen | 385
Ano, vrátí to pole, protože příjemce (signalReceiver) je formulář a jeho signál je submit. To ale nemění důvod, proč je členská proměnná signal presenteru private a ne protected.
Mimochodem, úprava na $this->signal[1]
teoreticky může
způsobit nějaké chybičky (asi notice), pokud je getSignal()
vrátí NULL.
Editoval Ola (4. 2. 2010 20:11)