<?php
namespace Cms\ContainerBundle\Entity;
use Cms\ContainerBundle\Entity\Containers\GenericContainer;
use Cms\ContainerBundle\Entity\Containers\IntranetContainer;
use Cms\ContainerBundle\Entity\Containers\PersonalContainer;
use Cms\ContainerBundle\Entity\Containers\StorageContainer;
use Cms\ContainerBundle\Entity\Containers\ThemeSettingsTrait;
use Cms\ContainerBundle\Service\ContainerWriteableInterface;
use Cms\CoreBundle\Entity\HtmlOverrides;
use Cms\CoreBundle\Model\EntityRestoreInterface;
use Cms\CoreBundle\Model\EntityRestoreTrait;
use Cms\CoreBundle\Model\HtmlOverridableInterface;
use Cms\CoreBundle\Model\Interfaces\Nestable\NestableInterface;
use Cms\CoreBundle\Model\Interfaces\Nestable\NestableTrait;
use Cms\CoreBundle\Model\Interfaces\Loggable\LoggableInterface;
use Cms\DomainBundle\Entity\Domain;
use Cms\ThemeBundle\Model\ThemeOverridableInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Cms\TenantBundle\Entity\TenantedEntity;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Represents an object that holds module data.
* Containers belong to a site, and are built in a tree hierarchy.
* They work similar to something like folders in a filesystem.
* TODO: unique index on slug, level, and site
*
* Class Container
* @package Cms\ContainerBundle\Entity
*
* @method Container getParent();
* @method ArrayCollection|Container[] getChildren();
*
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(
* repositoryClass = "Cms\ContainerBundle\Doctrine\ContainerRepository"
* )
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(
* name = "_discr",
* type = "string"
* )
* @ORM\DiscriminatorMap({
* GenericContainer::DISCR = "Cms\ContainerBundle\Entity\Containers\GenericContainer",
* PersonalContainer::DISCR = "Cms\ContainerBundle\Entity\Containers\PersonalContainer",
* IntranetContainer::DISCR = "Cms\ContainerBundle\Entity\Containers\IntranetContainer",
* StorageContainer::DISCR = "Cms\ContainerBundle\Entity\Containers\StorageContainer"
* })
* @ORM\Table(
* name = "cms__container__container",
* uniqueConstraints = {
* @ORM\UniqueConstraint(
* name = "uidx__unique__container",
* columns = {
* "tenant",
* "account",
* "parent",
* "name"
* }
* ),
* @ORM\UniqueConstraint(
* name = "uidx__unique__slug",
* columns = {
* "tenant",
* "account",
* "parent",
* "slug"
* }
* ),
* }
* )
* @Gedmo\Tree(
* type = "nested"
* )
*/
abstract class Container extends TenantedEntity implements
NestableInterface,
ThemeOverridableInterface,
HtmlOverridableInterface,
ContainerWriteableInterface,
EntityRestoreInterface,
LoggableInterface
{
use NestableTrait;
use ThemeSettingsTrait;
use EntityRestoreTrait;
use ContainerRestoreTrait;
const DISCR = null;
const ROUTING_SLUG = null;
/**
* The container that acts as the parent for this one.
* If null, this means that the container is at the root.
*
* @var Container
*
* @Gedmo\TreeParent
* @ORM\ManyToOne(
* targetEntity = "Cms\ContainerBundle\Entity\Container",
* inversedBy = "children"
* )
* @ORM\JoinColumn(
* name = "parent",
* referencedColumnName = "id",
* onDelete = "CASCADE"
* )
*/
protected $parent = null;
/**
* The immediate children of the container (i.e. those whose parent is this one).
*
* @var ArrayCollection|Container[]
*
* @ORM\OneToMany(
* targetEntity = "Cms\ContainerBundle\Entity\Container",
* mappedBy = "parent"
* )
* @ORM\OrderBy({
* "name" = "ASC"
* })
*/
protected $children;
/**
* Display name for the container.
*
* @var string
*
* @ORM\Column(
* type = "string",
* nullable = false
* )
*
* @Groups({"department", "department_minimal"})
*/
protected $name;
/**
* @var string
*
* @ORM\Column(
* type = "string",
* nullable = false,
* unique = false
* )
*/
protected $slug;
/**
* @var Domain
*
* @ORM\OneToOne(
* targetEntity = "Cms\DomainBundle\Entity\Domain"
* )
* @ORM\JoinColumn(
* name = "domain",
* referencedColumnName = "id",
* onDelete = "SET NULL"
* )
*/
protected $domain;
/**
* @var ModuleFlags
* @ORM\Embedded(
* class = "ModuleFlags",
* columnPrefix = "moduleFlags_"
* )
*/
protected $moduleFlags;
/**
* @var HtmlOverrides
*
* @ORM\Embedded(
* class = "Cms\CoreBundle\Entity\HtmlOverrides",
* columnPrefix = "htmlOverrides_"
* )
*/
protected $htmlOverrides;
/**
* @var bool
* @ORM\Column(type = "boolean", nullable = true, options = {"default" = true})
*/
protected $hidden = true;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = true
* )
*/
protected $color;
/**
* @var string|null
*
* @ORM\Column(
* type = "string",
* nullable = true
* )
*/
protected $code = null;
/**
* @var bool
*
* @ORM\Column(
* type = "boolean",
* nullable = false,
* options = {
* "default" = false,
* },
* )
*/
protected bool $schoolNowMigrated = false;
/**
* @return bool
*/
public function isSchoolNow(): bool
{
return $this->getTenant()->isSchoolNow() || $this->isSchoolNowMigrated();
}
/**
* @return bool
*/
public function isSchoolNowMigrated(): bool
{
return $this->schoolNowMigrated;
}
/**
* @param bool $schoolNowMigrated
* @return $this
*/
public function setSchoolNowMigrated(bool $schoolNowMigrated): self
{
$this->schoolNowMigrated = $schoolNowMigrated;
return $this;
}
/**
* @return bool
*/
public function isRoot()
{
return empty($this->getParent());
}
/**
* @return int
*/
public function getColor()
{
return $this->color;
}
/**
* @param int $value
* @return $this
*/
public function setColor($value)
{
$this->color = $value;
return $this;
}
/**
* @return boolean
*/
public function isHidden()
{
return $this->hidden;
}
/**
* @param boolean $hidden
* @return $this
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
*
*/
public function __construct()
{
$this->children = new ArrayCollection();
$this->moduleFlags = new ModuleFlags();
$this->htmlOverrides = new HtmlOverrides();
}
/**
* @return string
*/
public function getType()
{
return static::DISCR;
}
/**
* {@inheritdoc}
*/
public function getInnerLayoutOverride()
{
return $this->getDefaultInnerLayout();
}
/**
* {@inheritdoc}
*/
public function getOuterLayoutOverride()
{
return $this->getDefaultOuterLayout();
}
/**
* {@inheritdoc}
*/
public function getThemeOverride()
{
return $this->getDefaultTheme();
}
/**
* TODO: this is a hack for entity fields needing tree of these things...
*
* @return string
*/
public function __toString()
{
$padding = '';
for ($i = 0; $i < $this->getLevel(); $i++) {
$padding .= ' > ';
}
return $padding . $this->getName();
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* @return Domain
*/
public function getDomain()
{
return $this->domain;
}
/**
* @param Domain $value
* @return $this
*/
public function setDomain(Domain $value = null)
{
$this->domain = $value;
return $this;
}
/**
* @param string $value
* @return $this
*/
public function setName($value)
{
$this->name = $value;
return $this;
}
/**
* @param string $value
* @return $this
*/
public function setSlug($value)
{
$this->slug = $value;
return $this;
}
/**
* @return ModuleFlags
*/
public function getModuleFlags()
{
return $this->moduleFlags->associateDepartment($this);
}
/**
* @return HtmlOverrides
*/
public function getHtmlOverrides()
{
return $this->htmlOverrides;
}
/**
* {@inheritdoc}
*/
public function getBodyClass()
{
return $this->getHtmlOverrides()->getBodyClass();
}
/**
* {@inheritdoc}
*/
public function getHeadScripts()
{
return $this->getHtmlOverrides()->getHeadScripts();
}
/**
* {@inheritdoc}
*/
public function getTopScripts()
{
return $this->getHtmlOverrides()->getTopScripts();
}
/**
* {@inheritdoc}
*/
public function getBottomScripts()
{
return $this->getHtmlOverrides()->getBottomScripts();
}
/**
* Gets all of the ancestors (parents, grandparents, etc) of this container.
* Returns them with the "youngest" ancestor first.
* This should only be used when ancestors are already pre-loaded in the ORM.
* If not, it generates a lot of queries as each ancestor is found individually through ORM lazy loading.
*
* @return array|Container[]
*/
public function getAncestors()
{
$ancestors = [];
$current = $this->getParent();
while ( ! empty($current)) {
$ancestors[] = $current;
$current = $current->getParent();
}
return array_reverse($ancestors);
}
/**
* {@inheritdoc}
*/
public function getLoggableDetails()
{
return array(
'id' => $this->getId(),
'name' => $this->getName(),
);
}
/**
* @return string|null
*/
public function getCode(): ?string
{
return $this->code;
}
/**
* @param string|null $code
* @return $this
*/
public function setCode(?string $code = null): self
{
if (empty($code)) {
$code = null;
}
$this->code = $code;
return $this;
}
}