<?php
namespace App\Entity\Repository;
use App\Entity\Page;
use App\Entity\Route;
use Doctrine\ORM\Query;
use Gedmo\Translatable\Query\TreeWalker\TranslationWalker;
use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
class PageRepository extends NestedTreeRepository
{
private bool $multilingual = false;
/**
* @return Page[]
*/
public function getTree()
{
$queryBuilder = $this->getNodesHierarchyQueryBuilder();
$queryBuilder->orderBy('node.lft');
return $queryBuilder->getQuery()->getResult();
}
/**
* @param null $locale
*
* @return Page[]
*/
public function getHeaderNavigation($locale = null)
{
$headerNavigation = $this->findOneBy([
'alias' => Page::GROUP_TYPE_HEADER_NAVIGATION,
]);
$pages = $this->getNavigation($headerNavigation, true, 'lft');
foreach ($pages as &$page) {
$this->filterChildrenByShowInMenu($page);
$this->realSymlink($page);
}
return $pages;
}
private function filterChildrenByShowInMenu(Page $page): Page
{
$page->setChildren($page->getChildren()->filter(function (Page $page) {
return $page->isShowInMenu();
}));
foreach ($page->getChildren() as $child) {
$this->filterChildrenByShowInMenu($child);
}
return $page;
}
/**
* @param null $locale
*
* @return Page[]
*/
public function getFooterNavigation($locale = null)
{
$footerNavigation = $this->findOneBy([
'alias' => Page::GROUP_TYPE_FOOTER_NAVIGATION,
]);
if (!$footerNavigation) {
return [];
}
$pages = $this->getNavigation($footerNavigation, false, 'lft');
/** @var Page $page */
foreach ($pages as &$page) {
if ($locale) {
$page->setRoutes($page->getRoutes()->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
if (Page::PAGETYPE_SYMLINK === $page->getType()) {
$symLinkedPage = $page->getSymlinkedPage();
$symLinkedPage->setRoutes($symLinkedPage->getRoutes()
->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
}
}
$this->realSymlink($page);
}
return $pages;
}
/**
* @param null $locale
*
* @return Page[]
*/
public function getFooterBottomNavigation($locale = null)
{
$footerBottomNavigation = $this->findOneBy([
'alias' => Page::GROUP_TYPE_FOOTER_BOTTOM_NAVIGATION,
]);
if (!$footerBottomNavigation) {
return [];
}
$pages = $this->getNavigation($footerBottomNavigation, false, 'lft');
foreach ($pages as &$page) {
if ($locale) {
$page->setRoutes($page->getRoutes()->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
if (Page::PAGETYPE_SYMLINK === $page->getType()) {
$symLinkedPage = $page->getSymlinkedPage();
$symLinkedPage->setRoutes($symLinkedPage->getRoutes()
->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
}
}
$this->realSymlink($page);
}
return $pages;
}
/**
* @param null $locale
*
* @return Page[]
*/
public function getTopNavigation($locale = null)
{
$topNavigation = $this->findOneBy([
'alias' => Page::GROUP_TYPE_WEBRING,
]);
$pages = $this->getNavigation($topNavigation, true, 'lft');
foreach ($pages as &$page) {
if ($locale) {
$page->setRoutes($page->getRoutes()->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
if (Page::PAGETYPE_SYMLINK === $page->getType()) {
$symLinkedPage = $page->getSymlinkedPage();
$symLinkedPage->setRoutes($symLinkedPage->getRoutes()
->filter(function (Route $route) use ($locale) {
return $route->getLocale() === $locale;
}));
}
}
$this->filterChildrenByShowInMenu($page);
$this->realSymlink($page);
}
return $pages;
}
public function findDeleted(): array
{
$this->_em->getFilters()->disable('softdeleteable');
$qb = $this->createQueryBuilder('p');
$qb->where('p.deletedAt IS NOT NULL')
->andWhere('p.type = :type')
->setParameter('type', 'page');
return $qb->getQuery()
->getResult();
}
/**
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function findOneDeleted(int $id): Page
{
$this->_em->getFilters()->disable('softdeleteable');
$qb = $this->createQueryBuilder('p');
$qb->where('p.id = :id')
->setParameter('id', $id);
return $qb->getQuery()
->getSingleResult();
}
private function realSymlink(Page $page)
{
if (
'symlink' === $page->getType() &&
$page->getSymlinkedPage()->getRoutes()->first() &&
'' !== $page->getSymlinkedPage()->getRoutes()->first()->getName()
) {
foreach ($page->getSymlinkedPage()->getRoutes() as &$route) {
$route->setName(
str_replace(Route::ALIAS_PREFIX, '', $route->getName())
);
}
}
return $page;
}
/**
* @param null $node
* @param false $direct
* @param null $sortByField
* @param string $direction
* @param false $includeNode
*
* @return int|mixed|string
*/
public function getNavigation(
$node = null,
$direct = false,
$sortByField = null,
$direction = 'ASC',
$includeNode = false
) {
$queryBuilder = $this->getChildrenQueryBuilder($node, $direct, $sortByField, $direction,
$includeNode);
$queryBuilder->andWhere('node.showInMenu = true');
$queryBuilder->leftJoin('node.routes', 'routes');
$queryBuilder->addSelect('routes');
$query = $queryBuilder->getQuery();
if ($this->multilingual) {
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, TranslationWalker::class);
}
/* @var Page[] $pages */
return $query->getResult();
}
/**
* Temporary solution to set multilingual.
*/
public function setMultilingual(bool $multilingual)
{
$this->multilingual = $multilingual;
}
}