<?php
namespace Cms\ModuleBundle\Doctrine;
use App\Doctrine\Repository\Content\LegacyProxySearch;
use App\Doctrine\Repository\Content\ObjectSearch;
use App\Util\Pagination;
use App\Util\Querying;
use Cms\ContainerBundle\Entity\Container;
use Cms\ContainerBundle\Entity\Containers\GenericContainer;
use Cms\CoreBundle\Model\GlobalSearchInterface;
use Cms\CoreBundle\Model\Interfaces\Lockable\LockableRepositoryInterface;
use Cms\CoreBundle\Model\Interfaces\Lockable\LockableRepositoryTrait;
use Cms\CoreBundle\Model\Search\SearchableInterface;
use Cms\CoreBundle\Model\Search\SearchableTrait;
use Cms\CoreBundle\Model\Search\Search;
use Cms\CoreBundle\Util\Doctrine\EntityRepository;
use Cms\ModuleBundle\Entity\ModuleSettings;
use Cms\ModuleBundle\Entity\Proxy;
use Cms\ModuleBundle\Model\Interfaces\Shareable\ShareableInterface;
use Cms\ModuleBundle\Model\Traits\FrontendActions\CascadingSharesRepositoryTrait;
use Cms\Modules\BlogBundle\Entity\ModuleSettings as BlogModuleSettings;
use Cms\Modules\CalendarBundle\Entity\ModuleSettings as CalendarModuleSettings;
use Cms\Modules\GalleryBundle\Entity\ModuleSettings as GalleryModuleSettings;
use Cms\Modules\NewsBundle\Entity\ModuleSettings as NewsModuleSettings;
use Cms\Modules\PeopleBundle\Entity\ModuleSettings as PeopleModuleSettings;
use Cms\Modules\QuestionBundle\Entity\ModuleSettings as QuestionModuleSettings;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Exception;
use Platform\SecurityBundle\Entity\Identity\Account;
/**
* Class ProxyRepository
*
* @package Cms\ModuleBundle\Doctrine
*
* @method Proxy findExact($id)
* @method array|Proxy[] findAll()
* @method array|Proxy[] findAllLocked()
*/
class ProxyRepository extends EntityRepository implements SearchableInterface, GlobalSearchInterface, LockableRepositoryInterface
{
use SearchableTrait;
use LockableRepositoryTrait;
use CascadingSharesRepositoryTrait;
/**
* @param Proxy $proxy
* @return array|Proxy[]
*/
public function findAllShares(Proxy $proxy): array
{
if ( ! $proxy instanceof ShareableInterface) {
return [];
}
return $this->queryMany(
$this->createQueryBuilder('shares')
->andWhere('shares.sharedProxy = :proxy')
->andWhere('shares.id <> :proxy')
->setParameter('proxy', $proxy->getId())
);
}
/**
* {@inheritdoc}
*/
public function search(Search $search, $space = null, ModuleSettings $settings = null)
{
if (empty($space) || ! ($space instanceof Proxy || $space instanceof Container)) {
throw new Exception('Second parameter must either a Container or Proxy object.');
}
// create query builder
$qb = $this->createQueryBuilder('nodes');
if ($space instanceof Container) {
if ($settings instanceof BlogModuleSettings || $settings instanceof CalendarModuleSettings || $settings instanceof NewsModuleSettings || $settings instanceOf GalleryModuleSettings || $settings instanceof PeopleModuleSettings || $settings instanceof QuestionModuleSettings) {
$space = $this->flattenContainers($space, ClassUtils::getClass($settings));
}
$qb
->andWhere('nodes.container IN (:container)')
->setParameter('container', $space);
}
return $this->query($qb, $search);
}
/**
* @param LegacyProxySearch $search
* @param int|null $limit
* @param int|null $offset
* @return Paginator
*/
public function schoolnow(
LegacyProxySearch $search,
?int $limit = null,
?int $offset = null
): Paginator
{
$qb = $this->createQueryBuilder('proxies');
if ($search->getVisibility() !== null) {
$qb
->andWhere('proxies.placeholder = :placeholder')
->setParameter('placeholder', ! $search->getVisibility());
}
if ($lookup = $search->getLookup()) {
$qb
->andWhere($qb->expr()->orX(
Querying::dqlLike('proxies.data_title LIKE :lookup')
))
->setParameter('lookup', Querying::likeAny($lookup));
}
if (
in_array($search->getFilter(), [ObjectSearch::FILTERS__MY_DRAFT, ObjectSearch::FILTERS__MY_PUBLISHED], true) &&
$search->getAccount() instanceof Account
) {
$qb
->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('proxies.touchedBy', $search->getAccount()->getId()),
$qb->expr()->andX(
$qb->expr()->isNull('proxies.touchedBy'),
$qb->expr()->eq('proxies.updatedBy', $search->getAccount()->getId())
),
$qb->expr()->andX(
$qb->expr()->isNull('proxies.touchedBy'),
$qb->expr()->isNull('proxies.updatedBy'),
$qb->expr()->eq('proxies.createdBy', $search->getAccount()->getId())
)
)
)
;
}
if (in_array($search->getFilter(), [ObjectSearch::FILTERS__MY_DRAFT, ObjectSearch::FILTERS__DRAFT], true)) {
$qb
->andWhere('proxies.placeholder = :placeholder')
->setParameter('placeholder', true)
;
}
if (in_array($search->getFilter(), [ObjectSearch::FILTERS__MY_PUBLISHED, ObjectSearch::FILTERS__PUBLISHED], true)) {
$qb
->andWhere('proxies.placeholder = :placeholder')
->setParameter('placeholder', false)
;
}
switch ($search->getSort()) {
case LegacyProxySearch::SORTS__NAME:
$qb
->addOrderBy('proxies.data_title', $search->getDirection());
break;
case LegacyProxySearch::SORTS__TIMESTAMP:
$qb
->addOrderBy('proxies.touchedAt', $search->getDirection())
->addOrderBy('proxies.data_title', 'ASC');
break;
}
return Pagination::paginateThenQuery(
$qb,
$limit,
$offset ?: 0
);
}
/**
* @return array|Proxy[]
*/
public function findAllWithContainers()
{
$builder = $this->createQueryBuilder('proxies');
$builder
->leftJoin('proxies.container', 'container');
return $this->queryMany($builder);
}
/**
* @param Container $container
* @param int $limit
* @param int $page
* @return array|Proxy[]
*/
public function findAllForContainer(Container $container, $limit = 0, $page = 0)
{
$qb = $this->createQueryBuilder('proxies')
->andWhere('proxies.container = :container')
->setParameter('container', $container);
return $this->queryMany($qb, $limit, $page);
}
/**
* {@inheritdoc}
*/
public function findAllForGlobalSearch($query)
{
return $this->queryMany(
$this->createQueryBuilder('proxy')
->leftJoin('proxy.container', 'container')
->andWhere('proxy.data_title LIKE :queryLike')
->setParameter('queryLike', '%' . $query . '%')
->andWhere('container INSTANCE OF :class')
->setParameter('class', GenericContainer::DISCR)
->addOrderBy('proxy.data_title', 'ASC')
);
}
/**
* @param $regex
* @param array $fields
* @return array|Proxy[]
*/
public function findByRegex($regex, array $fields)
{
if ( ! count($fields)) {
return [];
}
$proxyTable = $this->getClassMetadata()->getTableName();
//create native sql
$sql = "SELECT id FROM `$proxyTable`";
//add condition to native sql
foreach ($fields as $field) {
$where[] = "`$field` REGEXP(:regex)";
}
if (isset($where)) {
$sql .= " WHERE " . implode(" AND ", $where);
}
$stmt = $this->_em->getConnection()->prepare($sql);
$stmt->execute(
array(
'regex' => $regex,
)
);
//set parameters for returned only ids array
$stmt->setFetchMode(\PDO::FETCH_COLUMN, 0);
//get only proxies ids
$ids = $stmt->fetchAll();
if (count($ids) == 0) {
return [];
}
//find proxies by ids
$qb = $this->createQueryBuilder('p');
$expr = $qb->expr();
$qb->andWhere(
$expr->in('p.id', $ids)
);
return $this->queryMany($qb);
}
}