PresenterTree – Kompletní strom presenterů – už dost nářků!
- Filip Procházka
- Moderator | 4668
Zdravím,
dneska v noci jsem dopsal https://gist.github.com/705975 ale už
jsem neměl sílu to sem posílat, takže se podělím trochu
opožděně… :)
config, pokud jsme paranoidní, zapsat až za definici robot loaderu :)
service.Kdyby-PresenterTree = "Kdyby\\PresenterTree"
použití
$pt = Nette\Environment::getApplication->getContext()->getService("Kdyby\\PresenterTree");
dump($pt->presenters); // všechny presentery
dump($pt->getPresenters('Front')); // všechny presentery přímo ve `Front`
dump($pt->getPresenters('Front', TRUE)); // tohle tam přidá i ty, které jsou v submodulech
dump($pt->getPresenters('Front:Forum')); // všechny přímé potomky `FrontModule\ForumModule`
akce presenterů (načítá i podle šablon)
dump($pt->getActions('Front:Homepage')); // homepage actions?
dump($pt->getActions('Front:Client')); // damn that's a module... too bad, returns NULL
moduly
dump($pt->modules); // root modules
dump($pt->getModules('Front')); // directry in front
dump($pt->getModules('Front:Client')); // avalaible submodules?
možnosti jak zakázat indexování presenterů a akcí
abstract class BasePresenter extends Nette\Application\Presenter { } // one
/** @hideInTree */
class BasePresenter extends Nette\Application\Presenter { } // two
class BasePresenter extends Nette\Application\Presenter
{
/** @hideInTree */
public function actionDefault() { } // three
/** @hideInTree */
public function renderSomethink() { } // three
}
Při inicializaci se ověří platnost cache a popř. se vygeneruje nový strom, to znamená, že pokud nějaké třídy, které nejsou načtené v robot loaderu zavoláte až po prvním zavolání PresenterTree tak je prostě nevypíše. Ale to na localhostu nevadí, protože tam stačí dát 2× F5 a na produkčním je to fuk :)
TODO:
- formát, v jakém je uložený strom presenterů se možná ještě změní, protože jsem to ještě nepoužil v cílové komponentě (ano menu) a proto pokud to někomu nebude vyhovovat tak šup sem s protesty ať to dáme dohromady :)
Editoval HosipLan (18. 12. 2010 11:57)
- Aurielle
- Člen | 1281
Tak první bug (metoda getPresenters):
if (strpos(':', $nettePath) == 1) {
$nettePath = substr($nettePath, 1);
}
if (strpos(':', $nettePath) == strlen($nettePath)) {
$nettePath = substr($nettePath, 0, -1);
}
if ($all || $nettePath === NULL) {
return isset($this->cache['presenters']['all'][$nettePath]) ? $this->tree['presenters']['all'][$nettePath] : NULL;
}
V podmínkách mají být === (to samé v getMethods a getActions) a
v return má místo špatného tree
být cache
–
poté getPresenters funguje. Máš taky přehozené pořadí parametrů strpos
funkcí. volání metody buildPresenterTree – moje chyba, přidal jsem
si ji pro testování a pak na to zapomněl :D
Abych nespamoval, tak tady je opravená verze (+ jsem si přepsal namespace…) Změny by měly být všechny a pouze z tohoto příspěvku. https://gist.github.com/706828
- jsem napsal jednodušší implementaci buildActionTree, která spoléhá jen
na přítomnost render a action metod při detekci akcí (neprohledává
šablony), ale za to se pak ve výsledku neobjevují blbosti typu
:BaseAdmin:Auth:@layout
:
/**
* @return array
*/
private function buildActionTree($presenters)
{
$tree = array();
foreach ($presenters['all'][NULL] as $fullPath => $presenter) {
$ref = $presenter->getPresenterReflection();
$views = array();
$methods = array();
foreach($ref->getMethods() as $k => $v) {
if(!$v->hasAnnotation('hideInTree') && $v->isPublic())
$methods[] = $v->name;
}
foreach($i = new \RegexIterator(new \ArrayIterator($methods), '~^(action|render)(.*)~i', \RegexIterator::GET_MATCH) as $view) {
$views[] = $view[2];
}
$actions = array();
foreach ($views as $view) {
$view = lcfirst($view);
$actions[$view] = $fullPath.':'.$view;
}
if ($actions) {
$tree['all'][$presenter->presenterClass] = array_flip($actions);
$t =& $tree['byPresenter'];
foreach (String::split($presenter->module, '~:~') as $step) {
$t[$step] = isset($t[$step]) ? $t[$step] : array();
$t =& $t[$step];
}
$t[$presenter->name] = array_flip($actions);
}
}
return $tree;
}
Editoval gmvasek (19. 11. 2010 19:43)
- Filip Procházka
- Moderator | 4668
Škoda že gist neumí diff :)
S tím že si přepíšeš namespace tak nějak počítám :)
A jsem rád že to použil aspoň jeden člověk. Když jsem to sem hodil, bylo
slyšet hodně skepticismu :)
- Filip Procházka
- Moderator | 4668
Trošku jsem poladil https://gist.github.com/705975, snad by to teď mělo šlapat v betě.
- MIKI
- Člen | 34
Zdravim,
mam Nette verziu „Nette Framework 2.0-dev (revision 7616569 released on 2011–03–10)“, a ked som si vlozil najnovsiu verziu tohto doplnku, tak mi ladenka krici:
Service ‚robotLoader‘ not found.
private function getRobotLoader()
338: {
339: return $this->getContext()->getService("robotLoader");
340: }
tak som pridal do config.neon toto:
common:
service:
RobotLoader: Nette\Loaders\RobotLoader
a aktualne mi to krici:
ksort() expects parameter 1 to be array, null given
private function buildPresenterTree()
...
100: ksort($tree['all']);
premenna $tree je prazdne pole, array(0) {}
Viete co mam konkretne spravit aby to fungovalo, alebo si to mam zistovat sam? :)