Created
October 10, 2019 06:48
-
-
Save Skrip42/8dc165829e59b5dbd3bfed1685679164 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 App\Services; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
use WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs; | |
use Symfony\Component\HttpFoundation\RequestStack; | |
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
use Symfony\Component\Routing\RouterInterface; | |
use Symfony\Component\Security\Core\Security; | |
use ReflectionClass; | |
use Doctrine\Common\Annotations\AnnotationReader; | |
use Doctrine\Common\Annotations\CachedReader; | |
use Doctrine\Common\Cache\PhpFileCache; | |
use Symfony\Component\HttpKernel\KernelInterface; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; | |
class PageMap | |
{ | |
/** @var array $map */ private $map; | |
/** @var Breadcrumbs $breadcrumbs */ | |
private $breadcrumbs; | |
/** @var Security $security */ | |
private $security; | |
/** @var string $currentRoute*/ | |
private $currentRoute; | |
/** @var UrlGeneratorInterface $urlGenerator */ | |
private $urlGenerator; | |
/** @var RouterInterface $router */ | |
private $router; | |
/** @var KernelInterface $kernel*/ | |
private $kernel; | |
/** @var string $currentNodeName */ | |
private $currentNodeName = 'home'; | |
/** @var array $currentNode */ | |
private $currentNode; | |
/** @var array $paths */ | |
private $paths = []; | |
/** @var array $routeList */ | |
private $routeList; | |
/** @var array $routeMapDictinary */ | |
private $routeMapDictinary; | |
public function __construct( | |
Breadcrumbs $breadcrumbs, | |
RequestStack $request, | |
ContainerInterface $container, | |
UrlGeneratorInterface $urlGenerator, | |
RouterInterface $router, | |
Security $security, | |
KernelInterface $kernel | |
) { | |
$this->router = $router; | |
$this->breadcrumbs = $breadcrumbs; | |
$this->urlGenerator = $urlGenerator; | |
$this->security = $security; | |
$this->kernel = $kernel; | |
$this->map = $container->getParameter('pagemap'); | |
if (!empty($request->getCurrentRequest())) { | |
$this->currentRoute = $request->getCurrentRequest()->get('_route'); | |
} | |
$this->generateFlat($this->map['home']); | |
$this->prepareAnnotation(); | |
$this->prepareMap($this->map['home']); | |
$this->paths = $this->generatePath($this->map['home'], ['home']); | |
$this->generateBreadCrumbs(); | |
dump($this->map); | |
} | |
/** | |
* Collect controllers annotation | |
* | |
* add is granted to node | |
*/ | |
private function prepareAnnotation() | |
{ | |
$reader = new CachedReader( | |
new AnnotationReader(), | |
new PhpFileCache($this->kernel->getProjectDir() . '/var/cache/phpmap/'), | |
true | |
); | |
foreach ($this->router->getRouteCollection() as $routeName => $route) { | |
if (empty($this->routeMapDictinary[$routeName])) { | |
continue; | |
} | |
list($classname, $methodname) = explode('::', $route->getDefaults()['_controller']); | |
$reflectionClass = new ReflectionClass($classname); | |
$classIsGranted = $reader->getClassAnnotation($reflectionClass, IsGranted::class); | |
$reflectionMethod = $reflectionClass->getMethod($methodname); | |
$methodIsGranted = $reader->getMethodAnnotation($reflectionMethod, IsGranted::class); | |
$granted = $methodIsGranted ?? $classIsGranted; | |
$this->routeMapDictinary[$routeName]['granted'] = !empty($granted) ? $granted->getAttributes() : false; | |
} | |
} | |
/** | |
* Create flat node dictinaris | |
* | |
* @param array &$node | |
* | |
* @return null | |
*/ | |
private function generateFlat(array &$node) | |
{ | |
if ($node['route']) { | |
$this->routeMapDictinary[$node['route']] = &$node; | |
} | |
if (!empty($node['childs'])) { | |
foreach ($node['childs'] as &$child) { | |
$this->generateFlat($child); | |
} | |
} | |
} | |
/** | |
* Recursive preparing map | |
* | |
* add url, expand property and fix nav property from granted | |
* | |
* @param array &$node | |
* | |
* @return bool is node expanded | |
*/ | |
private function prepareMap(array &$node) : bool | |
{ | |
if ($node['granted']) { | |
$node['nav'] = $node['nav'] && $this->security->isGranted($node['granted']); | |
} | |
if ($node['route'] && $node['nav']) { | |
$params = $node['default_param'] ?? []; | |
$node['url'] = $this->urlGenerator->generate( | |
$node['route'], | |
$params | |
); | |
} | |
$expand = false; | |
if (!empty($node['childs'])) { | |
foreach ($node['childs'] as &$child) { | |
$expand = $this->prepareMap($child) || $expand; | |
} | |
} | |
$node['expand'] = $expand; | |
return $node['nav'] || $expand; | |
} | |
/** | |
* Generate bread crumbs for current page | |
* | |
* @return null | |
*/ | |
private function generateBreadCrumbs() | |
{ | |
$path = $this->getPath(); | |
$nodes = $this->map; | |
foreach ($path as $nodeName) { | |
$node = $nodes[$nodeName]; | |
if (!empty($node['route']) && $node['route'] !== $this->currentRoute) { | |
$params = $node['default_param'] ?? []; | |
$this->breadcrumbs->addRouteItem( | |
$node['title'], | |
$node['route'], | |
$params | |
); | |
} else { | |
$this->breadcrumbs->addItem($node['title']); | |
} | |
if (empty($node['childs'])) { | |
break; | |
} | |
$nodes = $node['childs']; | |
} | |
} | |
/** | |
* Get title for curent page | |
* | |
* @return string | |
*/ | |
public function getCurrentTitle() : string | |
{ | |
return $this->currentNode['title']; | |
} | |
/** | |
* Return page map | |
* | |
* @return array | |
*/ | |
public function getMap() : array | |
{ | |
return $this->map; | |
} | |
/** | |
* Return route => node dictinary | |
* | |
* @return array | |
*/ | |
public function getRouteDictinary() : array | |
{ | |
return $this->routeMapDictinary; | |
} | |
/** | |
* Return path to current page | |
* | |
* @return array | |
*/ | |
public function getPath() : array | |
{ | |
return $this->paths[$this->currentNodeName]; | |
} | |
/** | |
* Generate path dictinary | |
* | |
* @param array $node | |
* @param array $path | |
* | |
* @return array | |
*/ | |
private function generatePath(array $node, array $path) : array | |
{ | |
$nodeName = end($path); | |
if (!empty($node['route']) && $node['route'] == $this->currentRoute) { | |
$this->currentNodeName = $nodeName; | |
$this->currentNode = $node; | |
} | |
$flat = []; | |
$flat[$nodeName] = $path; | |
if (!empty($node['childs'])) { | |
foreach ($node['childs'] as $name => $child) { | |
foreach ($this->generatePath($child, array_merge($path, [$name])) as $eln => $el) { | |
$flat[$eln] = $el; | |
}; | |
} | |
} | |
return $flat; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment