-
-
Save Aurielle/706828 to your computer and use it in GitHub Desktop.
PresenterTree - fixed verze
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
service.PHPin-Tools-PresenterTree.factory = "\PHPin\Tools\PresenterTree::createPresenterTree" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require LIBS_DIR . '/Nette/loader.php'; | |
Nette\Environment::loadConfig(); | |
$pt = Nette\Environment::getApplication->getContext()->getService('PHPin\Tools\PresenterTree'); | |
# presenters | |
dump($pt->presenters); // all of them! | |
dump($pt->getPresenters('Front')); // directry in front | |
dump($pt->getPresenters('Front', TRUE)); // even those in submodules! | |
dump($pt->getPresenters('Front:Forum')); // wanna have a nice menu in forum ? :) | |
# modules | |
dump($pt->modules); // root modules | |
dump($pt->getModules('Front')); // directry in front | |
dump($pt->getModules('Front:Client')); // avalaible submodules? | |
# actions | |
dump($pt->getActions('Front:Homepage')); // homepage actions? | |
dump($pt->getActions('Front:Client')); // damn that's a module... too bad, returns NULL | |
foreach ($pt->getPresenters('Front') as $presenter) { | |
dump($presenter->actions); // | |
} | |
# excluding presenters & actions | |
abstract class BasePresenter extends Nette\Application\Presenter { } // one | |
/** @hideInTree */ | |
abstract class BasePresenter extends Nette\Application\Presenter { } // two | |
abstract class BasePresenter extends Nette\Application\Presenter | |
{ | |
/** @hideInTree */ | |
public function actionDefault() { } // three | |
/** @hideInTree */ | |
public function renderSomethink() { } // three | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PHPin\Tools; | |
use Nette; | |
use Nette\Reflection\ClassReflection; | |
/** | |
* @author Filip Procházka <hosiplan@kdyby.org> | |
*/ | |
class PresenterInfo extends Nette\Object | |
{ | |
/** @var string */ | |
private $name; | |
/** @var string */ | |
private $module; | |
/** @var string */ | |
private $class; | |
/** @var array */ | |
private $actions; | |
/** @var PHPin\Tools\PresenterTree */ | |
private $tree; | |
/** | |
* @param string $name | |
* @param string $module | |
* @param string $class | |
*/ | |
public function __construct($name, $module, $class) | |
{ | |
$this->name = $name; | |
$this->module = $module; | |
$this->class = $class; | |
} | |
/** | |
* @return bool | |
*/ | |
public function isPublic() | |
{ | |
$ref = $this->getPresenterReflection(); | |
return !$ref->hasAnnotation('hideInTree'); | |
} | |
/** | |
* @return Nette\Reflection\ClassReflection | |
*/ | |
public function getPresenterReflection() | |
{ | |
return new ClassReflection($this->getPresenterClass()); | |
} | |
/** | |
* @return array | |
*/ | |
public function getActions() | |
{ | |
if ($this->actions === NULL) { | |
$this->actions = $this->getTree()->getPresenterActions($this); | |
} | |
return $this->actions; | |
} | |
/** | |
* @return string | |
*/ | |
public function getName($full = FALSE) | |
{ | |
return ($full ? ':' . $this->module . ':' : NULL) . $this->name; | |
} | |
/** | |
* @return string | |
*/ | |
public function getPresenterClass() | |
{ | |
return $this->class; | |
} | |
/** | |
* @return string | |
*/ | |
public function getModule() | |
{ | |
return $this->module; | |
} | |
public function __toString() | |
{ | |
return $this->getName(TRUE); | |
} | |
/** | |
* @return Kdyby\PresenterTree | |
*/ | |
public function getTree() | |
{ | |
if ($this->tree === NULL) { | |
$this->tree = $this->getContext()->getService("PHPin\\Tools\\PresenterTree"); | |
} | |
return $this->tree; | |
} | |
/** | |
* @return Nette\context | |
*/ | |
public function getContext() | |
{ | |
return Nette\Environment::getApplication()->getContext(); | |
} | |
public function __sleep() | |
{ | |
$properties = (array)$this; | |
unset($properties['tree'], $properties['actions']); | |
return array_keys($properties); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PHPin\Tools; | |
use Nette; | |
use Nette\Caching\Cache; | |
use Nette\Reflection\MethodReflection; | |
use Nette\String; | |
/** | |
* @author Filip Procházka <hosiplan@kdyby.org> | |
*/ | |
class PresenterTree extends Nette\Object | |
{ | |
const ALL = TRUE; | |
const DIRECT = FALSE; | |
// const TREE = 'tree'; // what does this mean? bad memmory :( | |
/** @var Nette\Caching\Cache */ | |
private $cache; | |
public function __construct() | |
{ | |
$cache = $this->getCache(); | |
if (!$this->isActual($cache)) { | |
$cache->save('presenters', $this->buildPresenterTree()); | |
$cache->save('modules', $this->buildModuleTree($cache['presenters'])); | |
$cache->save('actions', $this->buildActionTree($cache['presenters'])); | |
$this->isActual(TRUE); | |
} | |
} | |
/** | |
* @param Nette\Caching\Cache|bool $cache | |
* @return bool | |
*/ | |
private function isActual($cache = NULL) | |
{ | |
$classes = $this->getRobotLoader()->getIndexedClasses(); | |
$hash = md5(serialize($classes)); | |
if ($cache === TRUE) { | |
return $this->getCache()->save('hash', $hash); | |
} | |
if ($cache['hash'] != $hash) { | |
return FALSE; | |
} | |
return TRUE; | |
} | |
/** | |
* @return array | |
*/ | |
private function buildPresenterTree() | |
{ | |
$classes = array_keys($this->getRobotLoader()->getIndexedClasses()); | |
$tree = array(); | |
foreach ($i = new \RegexIterator(new \ArrayIterator($classes), "~.*Presenter$~") as $class) { | |
$nettePath = String::split(substr($class, 0, -9), '~Module\\\\~i'); | |
$presenter = array_pop($nettePath); | |
$module = strlen($module = $this->formatNettePath($nettePath)) ? substr($module, 1) : NULL; | |
$presenterInfo = new PresenterInfo($presenter, $module, $class); | |
$ref = $presenterInfo->getPresenterReflection(); | |
if (!$ref->isAbstract() && $presenterInfo->isPublic()) { | |
$t =& $tree['byModule']; | |
foreach ($nettePath as $step) { | |
$t[$step] = isset($t[$step]) ? $t[$step] : array(); | |
$t =& $t[$step]; | |
} | |
$t[$presenter] = $presenterInfo; | |
$steps = array(); | |
foreach ($nettePath as $step) { | |
$steps[] = $step; | |
$module = substr($this->formatNettePath($steps), 1); | |
$relative = substr($this->formatNettePath(array_diff($nettePath, $steps), $presenter), 1); | |
$tree['all'][NULL][':'.$module.':'.$relative] = $presenterInfo; | |
$tree['all'][$module][$relative] = $presenterInfo; | |
} | |
} | |
} | |
ksort($tree['all']); | |
return $tree; | |
} | |
/** | |
* @return array | |
*/ | |
private function buildModuleTree($presenters) | |
{ | |
$tree = array(); | |
$modules = array(); | |
foreach ($presenters['all'][NULL] as $fullPath => $presenter) { | |
if (!in_array($presenter->module, $modules)) { | |
$modules[] = $presenter->module; | |
} | |
} | |
foreach ($modules as $module) { | |
$nettePath = explode(':', $module); | |
$module = array_pop($nettePath); | |
$t =& $tree['byModule']; | |
foreach ($nettePath as $step) { | |
$t[$step] = isset($t[$step]) ? $t[$step] : array(); | |
$t =& $t[$step]; | |
} | |
$t = is_array($t) ? $t : array(); | |
$t[] = $module; | |
} | |
return $tree; | |
} | |
/** | |
* @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; | |
} | |
/** | |
* @param string $nettePath | |
* @param bool $all | |
* @return array | |
*/ | |
public function getPresenters($nettePath = NULL, $all = FALSE) | |
{ | |
if (strpos($nettePath, ':') === 0) { | |
$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->cache['presenters']['all'][$nettePath] : NULL; | |
} | |
$tree = $this->cache['presenters']['byModule']; | |
foreach (String::split($nettePath, '~:~') as $step) { | |
if (!isset($tree[$step])) { | |
return NULL; | |
} | |
$tree =& $tree[$step]; | |
} | |
return array_filter($tree, function($item) { return !is_array($item); }); | |
} | |
/** | |
* @param PHPin\Tools\PresenterInfo $presenter | |
* @return array | |
*/ | |
public function getPresenterActions(PresenterInfo $presenter) | |
{ | |
return $this->cache['actions']['all'][$presenter->class]; | |
} | |
/** | |
* @param string $nettePath | |
* @return array | |
*/ | |
public function getActions($nettePath) | |
{ | |
if (strpos($nettePath, ':') === 0) { | |
$nettePath = substr($nettePath, 1); | |
} | |
if (strpos($nettePath, ':') === strlen($nettePath)) { | |
$nettePath = substr($nettePath, 0, -1); | |
} | |
if (!$nettePath) { | |
return NULL; | |
} | |
$presenters = array(); | |
$tree = $this->cache['actions']['byPresenter']; | |
foreach (String::split($nettePath, '~:~') as $step) { | |
if (!isset($tree[$step])) { | |
return NULL; | |
} | |
$tree =& $tree[$step]; | |
} | |
return array_filter($tree, function($item) { return !is_array($item); }); | |
} | |
/** | |
* @param string $nettePath | |
* @param bool $all | |
* @return array | |
*/ | |
public function getModules($nettePath = NULL) | |
{ | |
if (strpos($nettePath, ':') === 0) { | |
$nettePath = substr($nettePath, 1); | |
} | |
if (strpos($nettePath, ':') === strlen($nettePath)) { | |
$nettePath = substr($nettePath, 0, -1); | |
} | |
if (!$nettePath) { | |
return array_filter($this->cache['modules']['byModule'], function($item) { return !is_array($item); }); | |
} | |
$presenters = array(); | |
$tree = $this->cache['modules']['byModule']; | |
foreach (String::split($nettePath, '~:~') as $step) { | |
if (!isset($tree[$step])) { | |
return NULL; | |
} | |
$tree =& $tree[$step]; | |
} | |
return array_filter($tree, function($item) { return !is_array($item); }); | |
} | |
/** | |
* @param array $steps | |
* @param string $presenter | |
* @return string | |
*/ | |
private function formatNettePath($steps, $presenter = NULL) | |
{ | |
return "" . ($steps ? ':'.implode(':', $steps) : NULL) . ($presenter ? ':'.$presenter : NULL); | |
} | |
/** | |
* @return Nette\Caching\Cache | |
*/ | |
private function getCache() | |
{ | |
if ($this->cache === NULL) { | |
$this->cache = Nette\Environment::getCache('PHPin.PresenterTree'); | |
} | |
return $this->cache; | |
} | |
/** | |
* @return Nette\Loaders\RobotLoader | |
*/ | |
private function getRobotLoader() | |
{ | |
return $this->getContext()->getService("Nette\\Loaders\\RobotLoader"); | |
} | |
/** | |
* @return Nette\Context | |
*/ | |
public function getContext() | |
{ | |
return Nette\Environment::getApplication()->getContext(); | |
} | |
/** | |
* @return PHPin\Tools\PresenterTree | |
*/ | |
public static function createPresenterTree() | |
{ | |
return new static; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment