<?php
namespace App\Repository;
use App\Entity\FreePage;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use App\Repository\SiteConfigRepository;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\Request;
/**
* @method FreePage|null find($id, $lockMode = null, $lockVersion = null)
* @method FreePage|null findOneBy(array $criteria, array $orderBy = null)
* @method FreePage[] findAll()
* @method FreePage[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class FreePageRepository extends ServiceEntityRepository
{
const UP = 'up';
const DOWN = 'down';
public function __construct(ManagerRegistry $registry, private SiteConfigRepository $siteConfigRepository)
{
parent::__construct($registry, FreePage::class);
}
public function getActiveOnlyQBuilder(string $alias = 'f', ?User $user = null): QueryBuilder
{
$qb = $this->createQueryBuilder($alias);
$roles = $user ? $user->getRoles() : ['ANONYMOUS'];
$role = reset($roles);
if ($role === User::ROLE_ADMIN) {
return $qb;
}else {
$qb->andWhere($qb->expr()->eq($alias . '.isPublic', true));
}
$qb->andWhere($alias . '.active = true');
return $qb;
}
/**
* @return FreePage[]
*/
public function findAllActive(?User $user = null, Request $request = null)
{
$siteConfig = $this->siteConfigRepository->findOneBy([]);
$isInstanceActive = $siteConfig ? $siteConfig->isInstanceActive() : false;
$instanceId = $request->getSession()->get('selected_instance_id');
$qb = $this->getActiveOnlyQBuilder('f', $user);
$qb->where('f.active = true');
if ($isInstanceActive && $instanceId !== null) {
$qb->andWhere('f.instance = :instanceId')
->setParameter('instanceId', $instanceId);
}
return $qb
->getQuery()
->getResult();
}
/**
* @return FreePage[]
*/
public function findAllActiveSorted()
{
return $this->getActiveOnlyQBuilder('f')
->orderBy('f.position', 'ASC')
->getQuery()
->getResult();
}
public function findOneActiveByRoute($route, ?User $user = null): ?FreePage
{
return $this->getActiveOnlyQBuilder('f', $user)
->andWhere('f.route = :route')
->setParameter('route', $route)
->getQuery()
->getOneOrNullResult();
}
public function persistAtLastPos(FreePage $instance)
{
$em = $this->getEntityManager();
$em->transactional(function ($em) use ($instance) {
$qb = $em->createQueryBuilder();
$qb
->from('App:FreePage', 'p')
->select('MAX(p.position)');
$query = $qb->getQuery();
$res = $query->getOneOrNullResult();
$current = $res ? array_pop($res) : 0;
$instance->setPosition($current + 1);
$em->persist($instance);
});
}
private static function swapPositions(?FreePage $page1, ?FreePage $page2)
{
$pos1 = $page1->getPosition();
$pos2 = $page2->getPosition();
$page1->setPosition($pos2);
$page2->setPosition($pos1);
return [$page1, $page2];
}
private function movePage(string $direction, FreePage $page)
{
$em = $this->getEntityManager();
$em->transactional(function ($em) use ($page, $direction) {
$qb = $em->createQueryBuilder();
$qb
->from('App:FreePage', 'p')
->addSelect('p')
->setMaxResults(1)
->setParameter('current_pos', $page->getPosition());
if ($direction == self::DOWN) {
$qb->orderBy('p.position', 'ASC');
$qb->andWhere('p.position > :current_pos');
} else {
$qb->orderBy('p.position', 'DESC');
$qb->andWhere('p.position < :current_pos');
}
$query = $qb->getQuery();
$next = $query->getOneOrNullResult();
if (!is_null($next)) {
list($b1, $b2) = self::swapPositions($page, $next);
$em->persist($b1);
$em->persist($b2);
}
});
}
public function movePageDown(FreePage $page)
{
$this->movePage(self::DOWN, $page);
}
public function movePageUp(FreePage $page)
{
$this->movePage(self::UP, $page);
}
}