src/Entity/Page.php line 94

  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM,
  4.     Doctrine\DBAL\Types\Types,
  5.     Doctrine\Common\Collections\Collection,
  6.     Doctrine\Common\Collections\ArrayCollection;
  7. use Symfony\Component\Serializer\Annotation\Groups;
  8. use ApiPlatform\Metadata\ApiResource,
  9.     ApiPlatform\Metadata\ApiProperty,
  10.     ApiPlatform\Metadata\Get,
  11.     ApiPlatform\Metadata\GetCollection,
  12.     ApiPlatform\Metadata\Post,
  13.     ApiPlatform\Metadata\Put,
  14.     ApiPlatform\Metadata\Delete,
  15.     ApiPlatform\Metadata\ApiFilter,
  16.     ApiPlatform\Doctrine\Orm\Filter\OrderFilter,
  17.     ApiPlatform\Doctrine\Orm\Filter\SearchFilter,
  18.     ApiPlatform\Doctrine\Orm\Filter\ExistsFilter;
  19. use App\Entity\Trait\IdTrait,
  20.     App\Entity\Trait\UuidTrait,
  21.     App\Entity\Trait\OrdStatTrait,
  22.     App\Entity\Trait\TimestampableTrait,
  23.     App\Entity\Trait\TranslatableTrait,
  24.     App\Entity\Trait\Languages\LanguageableChildTrait,
  25.     App\Entity\Trait\ImportIdTrait,
  26.     App\Entity\Trait\Languages\SiteLanguagesTrait,
  27.     App\Entity\Trait\Media\ImageThumbableTrait,
  28.     App\Entity\Interface\TranslatableInterface,
  29.     App\Entity\Interface\LanguageableChildInterface,
  30.     App\Entity\Interface\OrdStatableInterface,
  31.     App\Entity\Interface\CloneableInterface,
  32.     App\Entity\Interface\LanguageableInterface,
  33.     App\Entity\Interface\ThumbableInterface,
  34.     App\Entity\Interface\BlockableInterface,
  35.     App\Entity\Interface\BlockInterface;
  36. use App\StateProcessor\CloneProcessor,
  37.     App\Security\Voter\CloneVoter,
  38.     App\DTO\CloneDTO,
  39.     App\Lib\Actions,
  40.     App\Filter\IriFilter,
  41.     App\Util\ClassUtils,
  42.     App\Enum\Language,
  43.     App\Repository\PageRepository,
  44.     App\Security\Voter\PageVoter;
  45. #[ApiResource(
  46.     description'Pages',
  47.     normalizationContext: ['groups' => [
  48.         'read',
  49.         'read:' self::class,
  50.         'read:' self::class . 'Translation'
  51.     ]],
  52.     denormalizationContext: ['groups' => ['write']],
  53.     security'is_granted("' Page::class . '")',
  54.     order: ['ord' => 'desc'],
  55.     operations: [
  56.         new GetCollection(),
  57.         new Post(
  58.             uriTemplate'/pages/clone',
  59.             inputCloneDTO::class,
  60.             processorCloneProcessor::class,
  61.             security'is_granted("' Actions::CLONE .'")',
  62.             securityMessageCloneVoter::MESSAGE,
  63.             securityPostDenormalize'is_granted("' Actions::CLONE . '", object)',
  64.             securityPostDenormalizeMessagePageVoter::EDIT_MESSAGE
  65.         ),
  66.         new Post(
  67.             denormalizationContext: ['groups' => ['write',  'post']],
  68.             securityPostDenormalize'is_granted("' Actions::CREATE '", object)',
  69.             securityPostDenormalizeMessagePageVoter::CREATE_MESSAGE
  70.         ),
  71.         new Get(),
  72.         new Put(
  73.             securityPostDenormalize'is_granted("' Actions::EDIT '", object)',
  74.             securityPostDenormalizeMessagePageVoter::EDIT_MESSAGE
  75.         ),
  76.         new Delete(
  77.             securityPostDenormalize'is_granted("' Actions::DELETE '", object)',
  78.             securityPostDenormalizeMessagePageVoter::DELETE_MESSAGE
  79.         ),
  80.     ],
  81.     extraProperties: ['standard_put' => false],
  82. )]
  83. #[ApiFilter(ExistsFilter::class, properties: ['parent'])]
  84. #[ApiFilter(SearchFilter::class, properties: ['idName' => 'exact'])]
  85. #[ApiFilter(IriFilter::class, properties: ['parent'])]
  86. #[ApiFilter(OrderFilter::class, properties: ['ord'])]
  87. #[ORM\Entity(repositoryClassPageRepository::class)]
  88. class Page implements
  89.     TranslatableInterface,
  90.     LanguageableInterface,
  91.     LanguageableChildInterface,
  92.     OrdStatableInterface,
  93.     CloneableInterface,
  94.     ThumbableInterface,
  95.     BlockableInterface
  96. {
  97.     use IdTrait,
  98.         UuidTrait,
  99.         OrdStatTrait,
  100.         TimestampableTrait,
  101.         TranslatableTrait,
  102.         LanguageableChildTrait,
  103.         SiteLanguagesTrait,
  104.         ImageThumbableTrait,
  105.         ImportIdTrait {
  106.             SiteLanguagesTrait::getPrintLanguage insteadof LanguageableChildTrait;
  107.         }
  108.     #[ApiProperty(description'Parent'readableLinkfalsewritableLinkfalse)]
  109.     #[Groups(['read''write'])]
  110.     #[ORM\ManyToOne(targetEntityPage::class, inversedBy'children')]
  111.     #[ORM\JoinColumn(onDelete'cascade')]
  112.     private ?Page $parent null;
  113.     #[ApiProperty(description'Children pages')]
  114.     #[Groups(['read'])]
  115.     #[ORM\OneToMany(targetEntityPage::class, mappedBy'parent')]
  116.     #[ORM\OrderBy(['ord' => 'DESC'])]
  117.     private Collection $children;
  118.     #[ApiProperty(description'Identifier name')]
  119.     #[Groups(['read:' self::class, 'openform'])]
  120.     #[ORM\Column(typeTypes::STRINGlength255uniquetruenullabletrue)]
  121.     private ?string $idName null;
  122.     #[ApiProperty(description'Can non-openform administrators publish/unpublish this page')]
  123.     #[Groups(['read:' self::class, 'openform'])]
  124.     #[ORM\Column(type'boolean'options: ['default' => true])]
  125.     private bool $isStatable true;
  126.     #[ApiProperty(description'Can non-openform administrators edit this page')]
  127.     #[Groups(['read:' self::class, 'openform'])]
  128.     #[ORM\Column(type'boolean'options: ['default' => true])]
  129.     private bool $isEditable true;
  130.     #[ApiProperty(description'Can non-openform administrators delete this page')]
  131.     #[Groups(['read:' self::class, 'openform'])]
  132.     #[ORM\Column(type'boolean'options: ['default' => true])]
  133.     private bool $isDeletable true;
  134.     #[ApiProperty(description'Can non-openform administrators create subpage of this page')]
  135.     #[Groups(['read:' self::class, 'openform'])]
  136.     #[ORM\Column(type'boolean'options: ['default' => true])]
  137.     private bool $isSubPageable true;
  138.     #[ApiProperty(description'Show in main menu')]
  139.     #[Groups(['read:' self::class, 'write'])]
  140.     #[ORM\Column(type'boolean'options: ['default' => false])]
  141.     private bool $mainMenu false;
  142.     #[ApiProperty(description'Blocks'writableLinkfalse)]
  143.     #[ORM\OneToMany(
  144.         targetEntityPageBlock::class,
  145.         mappedBy'parent',
  146.         cascade: ['persist''remove']
  147.     )]
  148.     #[ORM\OrderBy(['ord' => 'desc'])]
  149.     private Collection $blocks;
  150.     public function __construct(
  151.         ?string $idName,
  152.         ?Page $parent,
  153.         ?int $ord,
  154.         ?bool $stat,
  155.         ?array $languages,
  156.     ) {
  157.         $this->setUuid();
  158.         $this->idName $idName;
  159.         $this->parent $parent;
  160.         $ord !== null && $this->ord $ord;
  161.         $stat !== null && $this->stat $stat;
  162.         $this->translations = new ArrayCollection();
  163.         $this->children = new ArrayCollection();
  164.         $this->blocks = new ArrayCollection();
  165.         $this->thumbs = new ArrayCollection();
  166.         $this->setLanguages($languages ?? Language::DEFAULT_SITE);
  167.         $this->createdAt = new \DateTimeImmutable();
  168.         $this->updatedAt = new \DateTimeImmutable();
  169.     }
  170.     public function getParent(): ?Page
  171.     {
  172.         return $this->parent;
  173.     }
  174.     public function setParent(?Page $page): self
  175.     {
  176.         $this->parent $page;
  177.         return $this;
  178.     }
  179.     public function getChildren(): Collection
  180.     {
  181.         return $this->children;
  182.     }
  183.     public function addChild(Page $child): self
  184.     {
  185.         if ($child->getUuid()->toString() === $this->getUuid()->toString()) {
  186.             return $this;
  187.         }
  188.         if (!$this->children->contains($child)) {
  189.             $this->children[] = $child;
  190.             $child->setParent($this);
  191.         }
  192.         return $this;
  193.     }
  194.     public function removeChild(Page $child): self
  195.     {
  196.         if ($this->children->contains($child)) {
  197.             $this->children->removeElement($child);
  198.             // set the owning side to null (unless already changed)
  199.             if ($child->getParent() === $this) {
  200.                 $child->setParent(null);
  201.             }
  202.         }
  203.         return $this;
  204.     }
  205.     public function resetChildren(): self
  206.     {
  207.         $this->children = new ArrayCollection();
  208.         return $this;
  209.     }
  210.     public function getIdName(): ?string
  211.     {
  212.         return $this->idName;
  213.     }
  214.     public function setIdName(?string $idName): self
  215.     {
  216.         $this->idName $idName;
  217.         return $this;
  218.     }
  219.     public function getIsStatable(): bool
  220.     {
  221.         return $this->isStatable;
  222.     }
  223.     public function setIsStatable(bool $isStatable): self
  224.     {
  225.         $this->isStatable $isStatable;
  226.         return $this;
  227.     }
  228.     public function getIsEditable(): bool
  229.     {
  230.         return $this->isEditable;
  231.     }
  232.     public function setIsEditable(bool $isEditable): self
  233.     {
  234.         $this->isEditable $isEditable;
  235.         return $this;
  236.     }
  237.     public function getIsDeletable(): bool
  238.     {
  239.         return $this->isDeletable;
  240.     }
  241.     public function setIsDeletable(bool $isDeletable): self
  242.     {
  243.         $this->isDeletable $isDeletable;
  244.         return $this;
  245.     }
  246.     public function getIsSubPageable(): bool
  247.     {
  248.         return $this->isSubPageable;
  249.     }
  250.     public function setIsSubPageable(bool $isSubPageable): self
  251.     {
  252.         $this->isSubPageable $isSubPageable;
  253.         return $this;
  254.     }
  255.     public function isMainMenu(): bool
  256.     {
  257.         return $this->mainMenu;
  258.     }
  259.     public function setMainMenu(bool $mainMenu): self
  260.     {
  261.         $this->mainMenu $mainMenu;
  262.         return $this;
  263.     }
  264.     public function getBlocks(): Collection
  265.     {
  266.         return $this->blocks;
  267.     }
  268.     public function addBlock(BlockInterface $block): self
  269.     {
  270.         if ($this->blocks->contains($block)) {
  271.             return $this;
  272.         }
  273.         $this->blocks[] = $block;
  274.         return $this;
  275.     }
  276.     public function removeBlock(BlockInterface $block): self
  277.     {
  278.         $this->blocks->removeElement($block);
  279.         return $this;
  280.     }
  281.     public function resetBlocks(): self
  282.     {
  283.         $this->blocks = new ArrayCollection();
  284.         return $this;
  285.     }
  286.     public function clone(): self
  287.     {
  288.         if ($this->idName) {
  289.             throw new \Exception('Predefined pages cannot be cloned.');
  290.         }
  291.         $clone = clone $this;
  292.         $clone->id null;
  293.         $clone->setUuid();
  294.         $clone->ord 0;
  295.         $clone->stat false;
  296.         $clone->importId null;
  297.         if ($clone->media) {
  298.             $clone->media $this->media->clone();
  299.             $clone->media->setRelated(self::class . ':' $clone->uuid->toString());
  300.         }
  301.         ClassUtils::cloneCollection($this$clone'translations');
  302.         $clone->synchronizeTranslations();
  303.         $nativeLanguage $clone->getLanguageableParent()->getNativeLanguage();
  304.         $nativeTranslation $clone->getTranslation($nativeLanguage);
  305.         $nativeTranslation->setTitle($nativeTranslation->getTitle() . ' [KOPIA]');
  306.         ClassUtils::cloneCollection($this$clone'blocks');
  307.         ClassUtils::cloneCollection($this$clone'thumbs');
  308.         $clone->resetChildren();
  309.         $clone->createdAt = new \DateTimeImmutable();
  310.         $clone->updatedAt = new \DateTimeImmutable();
  311.         return $clone;
  312.     }
  313. }