<?php
namespace App\Doctrine\Repository\Feed;
use App\Entity\Feed\AbstractEntry;
use App\Entity\System\School;
use App\Model\Searching\AbstractSearch;
use Cms\ContainerBundle\Entity\Container;
use Cms\CoreBundle\Util\DateTimeUtils;
use DateTimeInterface;
use Doctrine\ORM\QueryBuilder;
use Platform\SecurityBundle\Entity\Identity\Account;
use Products\NotificationsBundle\Entity\Profile;
class FeedSearch extends AbstractSearch
{
public const SORTS__DEFAULT = 'default';
public const DIRECTIONS = [
self::SORTS__DEFAULT => 'ASC',
];
public const STATUS__DRAFT = 'draft';
public const STATUS__SCHEDULED = 'scheduled';
public const STATUS__LIVE = 'live';
public const STATUSES = [
self::STATUS__DRAFT,
self::STATUS__SCHEDULED,
self::STATUS__LIVE,
];
public const AUTHOR__ME = 'me';
public const AUTHORS = [
self::AUTHOR__ME,
];
/**
* @var string|null
*/
protected ?string $lookup = null;
/**
* @var DateTimeInterface|null
*/
protected ?DateTimeInterface $cutoff = null;
/**
* @var int
*/
protected int $visibility = AbstractEntry::VISIBILITIES__PUBLISHED;
/**
* @var bool
*/
protected bool $boosted = true;
/**
* @var bool
*/
protected bool $deep = false;
/**
* @var bool
*/
protected bool $past = true;
/**
* @var bool
*/
protected bool $district = true;
/**
* @var array<int>
*/
protected array $schoolTypes = [];
/**
* @var array<School>
*/
protected array $schools = [];
/**
* @var array<Container>
*/
protected array $departments = [];
/**
* @var Account|Profile|null
*/
protected $user = null;
/**
* @var Container|null
*/
protected ?Container $root = null;
/**
* @var int|null
*/
protected ?int $channels = null;
/**
* @var string|null
*/
protected ?string $type = null;
/**
* @var string|null
*/
protected ?string $author = null;
/**
* @var string|null
*/
protected ?string $status = null;
/**
* @return string|null
*/
public function getLookup(): ?string
{
return $this->lookup;
}
/**
* @param string|null $lookup
* @return $this
*/
public function setLookup(?string $lookup): self
{
$this->lookup = $lookup ?: null;
return $this;
}
/**
* @return DateTimeInterface
*/
public function getCutoff(): DateTimeInterface
{
return $this->cutoff ?: DateTimeUtils::now();
}
/**
* @param DateTimeInterface|null $cutoff
* @return $this
*/
public function setCutoff(?DateTimeInterface $cutoff): self
{
$this->cutoff = $cutoff;
return $this;
}
/**
* @return int
*/
public function getVisibility(): int
{
return $this->visibility;
}
/**
* @param int|null $visibility
* @return $this
*/
public function setVisibility(?int $visibility): self
{
$this->visibility = $visibility ?: AbstractEntry::VISIBILITIES__PUBLISHED;
return $this;
}
/**
* @return bool
*/
public function getBoosted(): bool
{
return $this->boosted;
}
/**
* @param bool $boosted
* @return $this
*/
public function setBoosted(bool $boosted): self
{
$this->boosted = $boosted;
return $this;
}
/**
* @return bool
*/
public function isDeep(): bool
{
return $this->deep;
}
/**
* @param bool $deep
* @return $this
*/
public function setDeep(bool $deep): self
{
$this->deep = $deep;
return $this;
}
/**
* @return bool
*/
public function isPast(): bool
{
return $this->past;
}
/**
* @param bool $past
* @return $this
*/
public function setPast(bool $past): self
{
$this->past = $past;
return $this;
}
/**
* @return bool
*/
public function isFuture(): bool
{
return ! $this->isPast();
}
/**
* @param bool $future
* @return $this
*/
public function setFuture(bool $future): self
{
return $this->setPast( ! $future);
}
/**
* @return bool
*/
public function hasDistrict(): bool
{
return $this->district;
}
/**
* @param bool $district
* @return $this
*/
public function setDistrict(bool $district): self
{
$this->district = $district;
return $this;
}
/**
* @return array
*/
public function getSchoolTypes(): array
{
return $this->schoolTypes;
}
/**
* @param array<int>|int|null $schoolTypes
* @return $this
*/
public function setSchoolTypes($schoolTypes): self
{
$this->schoolTypes = [];
if ($schoolTypes) {
if ( ! is_array($schoolTypes)) {
$schoolTypes = [$schoolTypes];
}
foreach ($schoolTypes as $schoolType) {
$this->addSchoolType($schoolType);
}
}
return $this;
}
/**
* @param int $schoolType
* @return $this
*/
public function addSchoolType(int $schoolType): self
{
if ( ! in_array($schoolType, $this->schoolTypes, true)) {
$this->schoolTypes[] = $schoolType;
}
return $this;
}
/**
* @return array<School>
*/
public function getSchools(): array
{
return $this->schools;
}
/**
* @return School
*/
public function getSchool(): ?School
{
return !empty($this->schools) ? $this->schools[0] : null;
}
/**
* @param School
* @return $this
*/
public function setSchool($school): self
{
return $this->setSchools($school);
}
/**
* @param School|array<School>|null $schools
* @return $this
*/
public function setSchools($schools): self
{
$this->schools = [];
if ($schools) {
if ( ! is_array($schools)) {
$schools = [$schools];
}
foreach ($schools as $school) {
$this->addSchool($school);
}
}
return $this;
}
/**
* @param School $school
* @return $this
*/
public function addSchool(School $school): self
{
if ( ! in_array($school, $this->schools, true)) {
$this->schools[] = $school;
}
return $this;
}
/**
* @return array<Container>
*/
public function getDepartments(): array
{
return $this->departments;
}
/**
* @param Container|array<Container>|null $departments
* @return $this
*/
public function setDepartments($departments): self
{
$this->departments = [];
if ($departments) {
if ( ! is_array($departments)) {
$departments = [$departments];
}
foreach ($departments as $department) {
$this->addDepartment($department);
}
}
return $this;
}
/**
* @param Container $department
* @return $this
*/
public function addDepartment(Container $department): self
{
if ( ! in_array($department, $this->departments, true)) {
$this->departments[] = $department;
}
return $this;
}
/**
* @return Profile|Account|null
*/
public function getUser()
{
return $this->user;
}
/**
* @param Account|Profile|null $user
* @return $this
*/
public function setUser($user): self
{
if ($user && ! $user instanceof Account && ! $user instanceof Profile) {
throw new \RuntimeException();
}
$this->user = $user ?: null;
return $this;
}
/**
* @return Container|null
*/
public function getRoot(): ?Container
{
return $this->root;
}
/**
* @param Container|null $root
* @return $this
*/
public function setRoot(?Container $root): self
{
$this->root = $root;
return $this;
}
/**
* @param QueryBuilder $qb
* @return void
*/
public function filterCutoff(QueryBuilder $qb): void
{
$qb
->andWhere(
$this->isPast()
? $qb->expr()->lte('entries.timestamp', ':cutoff')
: $qb->expr()->gte('entries.timestamp', ':cutoff')
)
->setParameter(
'cutoff',
$this->getCutoff() ?: DateTimeUtils::now()
);
}
/**
* @param QueryBuilder $qb
* @return void
*/
public function orderCutoff(QueryBuilder $qb): void
{
$qb->addOrderBy(
'entries.timestamp',
$this->isPast() ? 'DESC' : 'ASC',
);
}
/**
* @return int|null
*/
public function getChannels(): ?int
{
return $this->channels;
}
/**
* @param int|null $channels
* @return self
*/
public function setChannels(?int $channels): self
{
$this->channels = $channels;
return $this;
}
/**
* @return string|null
*/
public function getType(): ?string
{
return $this->type;
}
/**
* @param string|null $type
* @return $this
*/
public function setType(?string $type): self
{
$this->type = $type;
return $this;
}
/**
* @return string|null
*/
public function getStatus(): ?string
{
return $this->status;
}
/**
* @param string|null $status
* @return $this
*/
public function setStatus(?string $status): self
{
$this->status = $status;
return $this;
}
/**
* @return string|null
*/
public function getAuthor(): ?string
{
return $this->author;
}
/**
* @param string|null $author
* @return $this
*/
public function setAuthor(?string $author): self
{
$this->author = $author;
return $this;
}
/**
* @return array
*/
public function jsonSerialize(): array
{
return array_merge(
parent::jsonSerialize(),
[
'lookup' => $this->getLookup(),
'cutoff' => $this->getCutoff()->format(DateTimeInterface::RFC3339),
'visibility' => $this->getVisibility(),
'boosted' => $this->getBoosted(),
'deep' => $this->isDeep(),
'past' => $this->isPast(),
'district' => $this->hasDistrict(),
'schoolTypes' => $this->getSchoolTypes(),
'schools' => array_map(
static function (School $school) {
return $school->getUlidAsString();
},
$this->getSchools(),
),
'departments' => array_map(
static function (Container $department) {
return $department->getId();
},
$this->getDepartments(),
),
'user' => $this->getUser() ? $this->getUser()->getId() : null,
'root' => $this->getRoot() ? $this->getRoot()->getId() : null,
],
);
}
}