<?php
namespace Products\NotificationsBundle\Entity;
use App\Entity\Shared\AliasableInterface;
use App\Entity\Shared\AliasableTrait;
use App\Entity\Shared\FlagsInterface;
use App\Entity\Shared\FlagsTrait;
use App\Entity\System\School;
use Cms\CoreBundle\Entity\OneRoster\OneRosterUser;
use Cms\CoreBundle\Model\Interfaces\Loggable\LoggableInterface;
use Cms\CoreBundle\Model\Interfaces\OneRosterable\OneRosterableInterface;
use Cms\CoreBundle\Model\Interfaces\OneRosterable\OneRosterableTrait;
use Cms\TenantBundle\Entity\TenantedEntity;
use Doctrine\ORM\Mapping as ORM;
use Reinder83\BinaryFlags\Bits;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Class AbstractList
* @package Products\NotificationsBundle\Entity
*
* @ORM\Entity(
* repositoryClass = "Products\NotificationsBundle\Doctrine\Repository\ListRepository",
* )
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(
* name = "discr",
* type = "string",
* )
* @ORM\DiscriminatorMap({
* Lists\DistrictList::DISCR = "Products\NotificationsBundle\Entity\Lists\DistrictList",
* Lists\StaticList::DISCR = "Products\NotificationsBundle\Entity\Lists\StaticList",
* Lists\SchoolList::DISCR = "Products\NotificationsBundle\Entity\Lists\SchoolList",
* Lists\ConditionList::DISCR = "Products\NotificationsBundle\Entity\Lists\ConditionList",
* })
* @ORM\Table(
* name = "notis__list",
* uniqueConstraints = {
* @ORM\UniqueConstraint(
* name = "uidx__tenant__name",
* columns = {
* "tenant",
* "name",
* },
* ),
* },
* )
* @UniqueEntity(
* fields = {"tenant", "name"},
* message = "List name is already used",
* )
*/
abstract class AbstractList extends TenantedEntity
implements
OneRosterableInterface,
FlagsInterface,
AliasableInterface,
LoggableInterface
{
use OneRosterableTrait;
use FlagsTrait;
use AliasableTrait;
const DISCRS = [
Lists\DistrictList::DISCR => Lists\DistrictList::class,
Lists\SchoolList::DISCR => Lists\SchoolList::class,
Lists\StaticList::DISCR => Lists\StaticList::class,
Lists\ConditionList::DISCR => Lists\ConditionList::class,
];
const DISCR = null;
const FLAGS = [
'fixed' => self::FLAGS__FIXED,
];
const FLAGS__FIXED = Bits::BIT_1;
/**
* @var string|null
*
* @ORM\Column(
* type = "string",
* nullable = false,
* )
*
* @Groups("list")
*/
protected ?string $name = null;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "unsigned" = true,
* "default" = 0,
* },
* )
*
* @Groups("list")
*/
protected int $types = 0;
/**
* @var int|null
*/
protected ?int $_count = null;
/**
* @var School|null
*
* @ORM\ManyToOne(
* targetEntity = School::class,
* )
* @ORM\JoinColumn(
* name = "school",
* referencedColumnName = "id",
* nullable = true,
* onDelete = "SET NULL",
* )
*/
protected ?School $school = null;
/**
* @return string
*/
public function discr(): string
{
return static::DISCR;
}
/**
* @param string|null $variant
* @return AbstractList
*/
public static function factory(?string $variant = null): AbstractList
{
return new static();
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
* @return $this
*/
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return int
*/
public function getTypes(): int
{
return $this->types;
}
/**
* @return array|int[]
*/
public function getTypesAsArray(): array
{
if ( ! $this->types) {
return [];
}
$result = [];
foreach (OneRosterUser::TYPES as $mask) {
if ($this->hasType($mask)) {
$result[] = $mask;
}
}
return $result;
}
/**
* @return array|string[]
*/
public function getTypeNames(): array
{
if ( ! $this->types) {
return [];
}
$result = [];
foreach (OneRosterUser::TYPES as $name => $mask) {
if ($this->hasType($mask)) {
$result[] = $name;
}
}
return $result;
}
/**
* @param int $types
* @return $this
*/
public function setTypes(int $types): self
{
$this->types = $types;
return $this;
}
/**
* @param int $type
* @return bool
*/
public function hasType(int $type): bool
{
return (($this->types & $type) > 0);
}
/**
* @param int $type
* @return $this
*/
public function markType(int $type): self
{
$this->types |= $type;
return $this;
}
/**
* @param int $type
* @return $this
*/
public function unmarkType(int $type): self
{
$this->types &= ~$type;
return $this;
}
/**
* @param int $type
* @param bool|null $toggle
* @return $this
*/
public function toggleType(int $type, ?bool $toggle = null): self
{
if ($toggle === null) {
return ($this->hasType($type)) ? $this->unmarkType($type) : $this->markType($type);
}
return ($toggle) ? $this->markType($type) : $this->unmarkType($type);
}
/**
* @return array|string[]
*/
public function getRoles(): array
{
$roles = [];
foreach ($this->getTypesAsArray() as $type) {
$roles = [
...$roles,
...OneRosterUser::TYPES_MAPPING[$type],
];
}
return array_values(array_unique($roles));
}
/**
* @return int|null
*/
public function getCount(): ?int
{
return $this->_count;
}
/**
* @param int|null $count
* @return $this
*/
public function setCount(?int $count): self
{
$this->_count = $count;
return $this;
}
/**
* @return School|null
*/
public function getSchool(): ?School
{
return $this->school;
}
/**
* @param School|null $school
* @return self
*/
public function setSchool(?School $school): self
{
$this->school = $school;
return $this;
}
/**
* @return bool
*/
public function isFixed(): bool
{
return $this->hasFlag(self::FLAGS__FIXED);
}
/**
* @return string
*/
public function getEntityClass(): string
{
return Profile::class;
}
/**
* {@inheritDoc}
*/
public function getLoggableDetails(): array
{
return [
'id' => (string) $this->getId(),
'title' => $this->getName(),
];
}
}