<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\ExistsFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Serializer\Filter\GroupFilter;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
use App\Annotation\CompanyCustomizable;
use App\Annotation\Exclusions;
use App\Repository\ChannelRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass=ChannelRepository::class)
* @ApiResource(
* normalizationContext={"groups"={"channel:read"}},
* denormalizationContext={"groups"={"channel:write"}},
* collectionOperations={
* "get"={
* "security"="is_granted('ROLE_USER')"
* },
* "post"={
* "security"="is_granted('ROLE_USER')"
* },
* "custom_add_remove_video_program_thematic_channel"={
* "description"="Add video to playlist's channel",
* "path"="/custom/playlist_channel/{action}/{slug}",
* "method"="POST",
* "controller"="App\Controller\Api\ChannelController::customAddOrRemoveVideoProgramThematicChannel",
* "deserialize"=false,
* "security"="is_granted('ROLE_USER')"
* },
* "post_update"={
* "security"="is_granted('ROLE_USER')",
* "path"="/channels/{id}",
* "description"="Update a Channel with method POST (using content-type: 'multipart')",
* "method"="POST",
* "controller"="App\Controller\Api\ChannelController::update"
* },
* "vitality_balance_recommended_channels_by_client"={
* "description"="Get vitality balance recommended channels by client.",
* "path"="/clients/{id}/vitality-balance/recommended-channels",
* "method"="GET",
* "controller"="App\Controller\Api\VitalityBalanceController::getVitalityBalanceRecommandedChannelsByClient",
* "security"="is_granted('ROLE_CLIENT')"
* },
* "vitality_balance_recommended_express_programs_by_client"={
* "description"="Get vitality balance recommended express_programs by client.",
* "path"="/clients/{id}/vitality-balance/recommended-express-programs",
* "method"="GET",
* "controller"="App\Controller\Api\VitalityBalanceController::getVitalityBalanceRecommandedExpressProgramsByClient",
* "security"="is_granted('ROLE_CLIENT')"
* }
* },
* itemOperations={
* "get"={
* "security"="is_granted('ROLE_USER')"
* },
* "delete"={
* "security"="is_granted('ROLE_USER')"
* },
* "patch"={
* "security"="is_granted('ROLE_USER')"
* }
* }
* )
* @ApiFilter(GroupFilter::class, arguments={
* "parameterName": "groups",
* "overrideDefaultGroups": true
* })
* @ApiFilter(SearchFilter::class, properties={
* "name": "partial", "active", "isThematic",
* "tvCompany.id": "exact", "tvCompany.name": "partial", "tvUser.id": "exact", "category.id": "exact",
* "objectives.id": "exact"
* })
* @ApiFilter(ExistsFilter::class, properties={"tvUser", "category"})
* @ApiFilter(OrderFilter::class, properties={"id", "name", "active", "category.name"})
* @ApiFilter(PropertyFilter::class,
* arguments={
* "parameterName"="fields",
* "overrideDefaultProperties"=true
* }
* )
* @CompanyCustomizable
* @Exclusions(exclusionsClass="App\Entity\ExclusionsChannel", property="exclusions_channels")
*/
class Channel
{
const VIDEO_TYPE = 'video';
const RECIPE_TYPE = 'recipe';
const AUDIO_TYPE = 'audio';
const TYPES = [
self::VIDEO_TYPE,
self::RECIPE_TYPE,
self::AUDIO_TYPE
];
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"channel:read", "channel:read:id", "homepage:read", "category:read", "stats", "slide:read", "day:read", "video:read",
* "search_engine", "objective:read", "channel_list", "channel_form", "channel_form_simple", "program_express_list"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"channel:read", "channel:read:name", "channel:write", "category:read", "stats", "slide:read", "homepage:read", "day:read",
* "video:read", "search_engine", "objective:read", "channel_list", "program_single_list", "video_list", "channel_form",
* "video_form_complete", "channel_form_simple", "objective_form_complete", "answer_recommended_objectives_edit", "program_express_list"})
* @Assert\NotBlank(message="channel.name")
*/
private $name;
/**
* @ORM\Column(type="boolean", options={"default": "1"})
* @Groups({"channel:read", "channel:read:active", "channel:write", "search_engine", "objective:read", "channel_list", "program_express_list"})
*/
private $active = true;
/**
* @ORM\Column(type="text")
* @Groups({"channel:read", "channel:read:content", "channel:write", "slide:read", "category:read", "search_engine", "objective:read", "program_express_list"})
*/
private $content;
/**
* @ORM\ManyToOne(targetEntity=Category::class, inversedBy="channels")
* @ORM\JoinColumn(nullable=true)
* @Groups({"channel:read", "channel:read:category", "channel:write", "search_engine", "objective:read", "slide:read", "channel_list", "program_express_list"})
*/
private $category;
/**
* @ORM\ManyToOne(targetEntity=Playlist::class, inversedBy="channels", cascade={"persist", "refresh", "remove"})
* @ORM\JoinColumn(nullable=false)
* @Groups({"homepage:read", "single_channel:read", "channel:read", "channel:read:playlist", "video:read", "search_engine", "objective:read", "channel_form"})
* @Assert\NotNull(message="channel.playlist")
* @ApiSubresource(maxDepth=1)
*/
private $playlist;
/**
* @ORM\OneToMany(targetEntity=Slide::class, mappedBy="channel")
*/
private $slides;
/**
* This is used for the customisation in the login page
* @ORM\ManyToOne(targetEntity=MediaObject::class)
* @Groups({"channel:read", "channel:read:image", "channel:write", "slide:read", "category:read", "stats", "search_engine", "objective:read", "program_express_list"})
*/
private $image;
/**
* @ORM\ManyToOne(targetEntity=TvCompany::class, inversedBy="channels")
*/
private $tvCompany;
/**
* @ORM\ManyToOne(targetEntity=Company::class, inversedBy="channels")
* @Groups({"channel:read", "channel:write"})
*/
private $company;
/**
* @ORM\ManyToOne(targetEntity=Channel::class, inversedBy="children")
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity=Channel::class, mappedBy="parent")
*/
private $children;
/**
* @ORM\Column(type="boolean", options={"default": "0"})
* @Groups({"channel:read", "channel:read:emptyChannel", "channel:write", "category:read", "stats", "slide:read", "homepage:read", "day:read", "search_engine", "objective:read"})
*/
private $emptyChannel = false;
/**
* @ORM\Column(type="boolean", options={"default": "0"})
* @Groups({"channel:read", "channel:read:isThematic", "channel:write", "category:read", "stats", "slide:read", "homepage:read", "day:read", "search_engine", "objective:read"})
*/
private $isThematic = false;
/**
* @ORM\OneToMany(targetEntity=ExclusionsChannel::class, mappedBy="channel", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
* @Groups({"channel:read", "channel:read:exclusionsChannels", "channel:write"})
*/
private $exclusionsChannels;
/**
* @ORM\Column(type="text", nullable=true)
* @Groups({"channel:read", "channel:read:contentPlaylist", "channel:write", "slide:read", "category:read", "search_engine", "objective:read"})
*/
private $contentPlaylist;
/**
* @ORM\ManyToMany(targetEntity=FiltersCategory::class, mappedBy="channels")
* @Groups({"channel:read", "channel:read:filtersCategories", "channel:write", "category:read", "search_engine", "objective:read"})
*/
private $filtersCategories;
/**
* @ORM\ManyToOne(targetEntity=TvUser::class, inversedBy="channels")
*/
private $tvUser;
/**
* @var array
* @Groups({"channel:read", "channel:read:moodAfterPostResponses"})
*/
public $moodAfterPostResponses = null;
/**
* @ORM\Column(name="`rank`", type="integer")
* @Groups({"channel:read", "channel:read:rank", "channel:write", "category:read", "stats", "slide:read", "homepage:read", "day:read",
* "search_engine", "objective:read", "channel_list"})
*/
private $rank;
/**
* @Groups({"channel:read", "channel:read:flags", "slide:read", "category:read", "search_engine", "objective:read"})
*/
public $flags = null;
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
* @Groups({"channel:read", "channel:read:createdAt", "channel:write", "slide:read", "category:read", "search_engine", "objective:read"})
*/
private $createdAt;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"channel:read", "channel:read:thematicMotivationEndPhrase", "channel:write", "category:read", "search_engine", "objective:read"})
*/
private $thematicMotivationEndPhrase;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"channel:read", "channel:read:type", "channel:write", "slide:read", "category:read", "search_engine", "objective:read"})
* @Assert\Choice(choices=self::TYPES)
*/
private $type;
/**
* @var int
* @Groups({"channel:read", "channel:read:videosCount", "slide:read", "channel_list", "program_express_list"})
*/
private $videosCount = 0;
/**
* @ORM\ManyToMany(targetEntity=TvTag::class)
* @Groups({"channel:read", "channel:read:tvTags", "channel:write"})
*/
private $tvTags;
/**
* @ORM\Column(type="text", nullable=true)
* @Groups({"channel:read", "channel:read:stringifyTags"})
*/
private $stringifyTags = '';
/**
* @var bool
* @Groups({"channel:read", "channel:read:excluded", "slide:read", "channel_list"})
*/
private $excluded = false;
/**
* @ORM\OneToMany(targetEntity=Video::class, mappedBy="defaultChannel")
*/
private $defaultVideos;
/**
* @ORM\ManyToMany(targetEntity=Objective::class, mappedBy="channels")
*/
private $objectives;
/**
* @ORM\Column(type="boolean", options={"default": 0})
* @Groups({"channel:read", "channel:read:itCanInterrest", "channel:write"})
*/
private $itCanInterrest = false;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Gedmo\Timestampable(on="update")
*/
private $updatedAt;
/**
* @ORM\OneToMany(targetEntity=ProgramEvent::class, mappedBy="channel", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
*/
private $programEvents;
/**
* Custom field isThematic = 1
* @var ?Video
* @Groups({"channel:read", "channel:read:currentVideo"})
*/
public $currentVideo;
/**
* Custom field isThematic = 1
* @var ?Video
* @Groups({"channel:read", "channel:read:previousVideo"})
*/
public $previousVideo;
/**
* Custom field isThematic = 1
* @var ?Video
* @Groups({"channel:read", "channel:read:nextVideo"})
*/
public $nextVideo;
/**
* Custom field isThematic = 1
* @var ?int
* @Groups({"channel:read", "channel:read:nextVideo"})
*/
public $videosCompletedCount = 0;
public function __construct()
{
$this->playlist = new Playlist();
$this->active = true;
$this->slides = new ArrayCollection();
$this->children = new ArrayCollection();
$this->isThematic = false;
$this->exclusionsChannels = new ArrayCollection();
$this->filtersCategories = new ArrayCollection();
$this->emptyChannel = false;
$this->content = "";
$this->rank = 999;
$this->thematicMotivationEndPhrase = "";
$this->type = null;
$this->tvTags = new ArrayCollection();
$this->defaultVideos = new ArrayCollection();
$this->objectives = new ArrayCollection();
$this->programEvents = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
$this->setCompany($category->getCompany());
return $this;
}
public function getPlaylist(): ?Playlist
{
return $this->playlist;
}
public function setPlaylist(?Playlist $playlist): self
{
$this->playlist = $playlist;
return $this;
}
/**
* @return Collection|Slide[]
*/
public function getSlides(): Collection
{
return $this->slides;
}
public function addSlide(Slide $slide): self
{
if (!$this->slides->contains($slide)) {
$this->slides[] = $slide;
$slide->setChannel($this);
}
return $this;
}
public function removeSlide(Slide $slide): self
{
if ($this->slides->removeElement($slide)) {
// set the owning side to null (unless already changed)
if ($slide->getChannel() === $this) {
$slide->setChannel(null);
}
}
return $this;
}
public function getTvCompany(): ?TvCompany
{
return $this->tvCompany;
}
public function setTvCompany(?TvCompany $tvCompany): self
{
$this->tvCompany = $tvCompany;
return $this;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(self $child): self
{
if (!$this->children->contains($child)) {
$this->children[] = $child;
$child->setParent($this);
}
return $this;
}
public function removeChild(self $child): self
{
if ($this->children->removeElement($child)) {
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
}
return $this;
}
/**
*
*/
public function getVideosCount(): int
{
return $this->videosCount;
}
/**
* @return mixed
*/
public function getImage()
{
return $this->image;
}
/**
* @param mixed $image
* @return Channel
*/
public function setImage($image): Channel
{
$this->image = $image;
return $this;
}
/**
* @Groups({"channel:write"})
*/
public function setImageFile($file = null): self
{
if($file instanceof UploadedFile) {
$image = empty($this->image) ? new MediaObject : $this->image;
$image->setFile($file);
$this->setImage($image);
}
return $this;
}
public function getEmptyChannel(): ?bool
{
return $this->emptyChannel;
}
public function setEmptyChannel(bool $emptyChannel): self
{
$this->emptyChannel = $emptyChannel;
return $this;
}
public function getIsThematic(): ?bool
{
return $this->isThematic;
}
public function setIsThematic(bool $isThematic): self
{
$this->isThematic = $isThematic;
return $this;
}
/**
* @return Collection|ExclusionsChannel[]
*/
public function getExclusionsChannels(): Collection
{
return $this->exclusionsChannels;
}
public function addExclusionsChannel(ExclusionsChannel $exclusionsChannel): self
{
if (!$this->exclusionsChannels->contains($exclusionsChannel)) {
$this->exclusionsChannels[] = $exclusionsChannel;
$exclusionsChannel->setChannel($this);
// Ajout des Exclusions de toutes les Videos liées a cette Chaines
$playlist = $this->getPlaylist();
if($playlist instanceof Playlist) {
foreach($playlist->getVideos()->toArray() as $video) {
$exclusionsVideo = new ExclusionsVideo;
$exclusionsVideo
->setVideo($video)
->setCompany($exclusionsChannel->getCompany())
->setCreatedAt(new \DateTime());
// Vérifier si il en existe pas deja un
$video->addExclusionsVideo($exclusionsVideo);
}
}
}
return $this;
}
public function removeExclusionsChannel(ExclusionsChannel $exclusionsChannel): self
{
if ($this->exclusionsChannels->removeElement($exclusionsChannel)) {
// set the owning side to null (unless already changed)
if ($exclusionsChannel->getChannel() === $this) {
$exclusionsChannel->setChannel(null);
// Retrait des Exclusion de toutes les Videos liées a cette Chaines
$playlist = $this->getPlaylist();
if($playlist instanceof Playlist) {
foreach($playlist->getVideos()->toArray() as $video) {
foreach ($video->getExclusionsVideos()->toArray() as $exclusionsVideo) {
if($exclusionsVideo->getCompany() === $exclusionsChannel->getCompany()) {
$video->removeExclusionsVideo($exclusionsVideo);
}
}
}
}
}
}
return $this;
}
public function getContentPlaylist(): ?string
{
return $this->contentPlaylist;
}
public function setContentPlaylist(?string $contentPlaylist): self
{
$this->contentPlaylist = $contentPlaylist;
return $this;
}
/**
* @return Collection|FiltersCategory[]
*/
public function getFiltersCategories(): Collection
{
return $this->filtersCategories;
}
public function addFiltersCategory(FiltersCategory $filtersCategory): self
{
if (!$this->filtersCategories->contains($filtersCategory)) {
$this->filtersCategories[] = $filtersCategory;
$filtersCategory->addChannel($this);
}
return $this;
}
public function removeFiltersCategory(FiltersCategory $filtersCategory): self
{
if ($this->filtersCategories->removeElement($filtersCategory)) {
$filtersCategory->removeChannel($this);
}
return $this;
}
public function getTvUser(): ?TvUser
{
return $this->tvUser;
}
public function setTvUser(?TvUser $tvUser): self
{
$this->tvUser = $tvUser;
return $this;
}
public function getRank(): ?int
{
return $this->rank;
}
public function setRank(?int $rank): self
{
$this->rank = $rank;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getThematicMotivationEndPhrase(): ?string
{
return $this->thematicMotivationEndPhrase;
}
public function setThematicMotivationEndPhrase(?string $thematicMotivationEndPhrase): self
{
$this->thematicMotivationEndPhrase = $thematicMotivationEndPhrase;
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(?string $type): self
{
$this->type = $type;
return $this;
}
/**
* @param int $videosCount
* @return Channel
*/
public function setVideosCount(int $videosCount): Channel
{
$this->videosCount = $videosCount;
return $this;
}
/**
* @return Collection|TvTag[]
*/
public function getTvTags(): Collection
{
return $this->tvTags;
}
/**
* @return Channel
* @Groups({"channel:write"})
*/
public function setTvTags(Collection $tvTags): self
{
$this->tvTags = $tvTags;
foreach ($this->tvTags as $tvTag) {
$this->stringifyTags .= "#".$tvTag->getName();
}
return $this;
}
public function addTvTag(TvTag $tvTag): self
{
if (!$this->tvTags->contains($tvTag)) {
$this->tvTags[] = $tvTag;
}
return $this;
}
public function removeTvTag(TvTag $tvTag): self
{
$this->tvTags->removeElement($tvTag);
return $this;
}
public function getStringifyTags(): ?string
{
return $this->stringifyTags;
}
public function setStringifyTags(?string $stringifyTags): self
{
$this->stringifyTags = $stringifyTags;
return $this;
}
/**
* @param bool $excluded
* @return Channel
*/
public function setExcluded(bool $excluded): Channel
{
$this->excluded = $excluded;
return $this;
}
/**
* @return bool
*/
public function isExcluded(): bool
{
return $this->excluded;
}
/**
* @return Collection|Video[]
*/
public function getDefaultVideos(): Collection
{
return $this->defaultVideos;
}
public function addDefaultVideo(Video $defaultVideo): self
{
if (!$this->defaultVideos->contains($defaultVideo)) {
$this->defaultVideos[] = $defaultVideo;
$defaultVideo->setDefaultChannel($this);
}
return $this;
}
public function removeDefaultVideo(Video $defaultVideo): self
{
if ($this->defaultVideos->removeElement($defaultVideo)) {
// set the owning side to null (unless already changed)
if ($defaultVideo->getDefaultChannel() === $this) {
$defaultVideo->setDefaultChannel(null);
}
}
return $this;
}
/**
* @return Collection|Objective[]
*/
public function getObjectives(): Collection
{
return $this->objectives;
}
/**
* @return Collection|Objective[]
*/
public function setObjectives(Collection $objectives): self
{
$this->objectives = $objectives;
return $this;
}
public function addObjective(Objective $objective): self
{
if (!$this->objectives->contains($objective)) {
$this->objectives[] = $objective;
$objective->addChannel($this);
}
return $this;
}
public function removeObjective(Objective $objective): self
{
if ($this->objectives->removeElement($objective)) {
$objective->removeChannel($this);
}
return $this;
}
public function getItCanInterrest(): ?bool
{
return $this->itCanInterrest;
}
public function setItCanInterrest(bool $itCanInterrest): self
{
$this->itCanInterrest = $itCanInterrest;
return $this;
}
/**
* @return Collection|ProgramEvent[]
*/
public function getProgramEvents(): Collection
{
return $this->programEvents;
}
public function addProgramEvent(ProgramEvent $programEvent): self
{
if (!$this->programEvents->contains($programEvent)) {
$this->programEvents[] = $programEvent;
$programEvent->setChannel($this);
}
return $this;
}
public function removeProgramEvent(ProgramEvent $programEvent): self
{
if ($this->programEvents->removeElement($programEvent)) {
// set the owning side to null (unless already changed)
if ($programEvent->getChannel() === $this) {
$programEvent->setChannel(null);
}
}
return $this;
}
}