<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
use ApiPlatform\Core\Serializer\Filter\GroupFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use App\Repository\PlaylistRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(repositoryClass=PlaylistRepository::class)
* @ApiResource(
* normalizationContext={"playlist:read"},
* denormalizationContext={"playlist:write"},
* collectionOperations={
* "get"={
* "security"="is_granted('ROLE_USER')"
* },
* "post"={
* "security"="is_granted('ROLE_USER')"
* }
* },
* itemOperations={
* "get"={
* "security"="is_granted('ROLE_USER')"
* },
* "patch"={
* "security"="is_granted('ROLE_ADMIN') or (is_granted('ROLE_USER') and object.getUser() == user)"
* },
* "delete"={
* "security"="is_granted('ROLE_ADMIN') or (is_granted('ROLE_USER') and object.getUser() == user)"
* },
* "user_patch"={
* "method"="PATCH",
* "security"="is_granted('ROLE_ADMIN') or (is_granted('ROLE_USER') and object.getUser() == user)",
* "controller"="App\Controller\Api\PlaylistController::userUpdate",
* "path"="/users/{user}/playlists/{id}",
* "openapi_context"={"summary"="Update playlist of a User"}
* },
* "user_remove"={
* "method"="DELETE",
* "security"="is_granted('ROLE_USER') and object.getUser() == user",
* "controller"="App\Controller\Api\PlaylistController::userRemove",
* "path"="/users/{user}/playlists/{id}",
* "openapi_context"={"summary"="Delete playlist of a User"}
* }
* }
* )
* @ApiFilter(SearchFilter::class, properties={"name": "partial", "user.id"})
* @ApiFilter(PropertyFilter::class,
* arguments={
* "parameterName"="fields",
* "overrideDefaultProperties"=true
* }
* )
* @ApiFilter(GroupFilter::class, arguments={
* "parameterName": "groups",
* "overrideDefaultGroups": true
* })
* @ORM\HasLifecycleCallbacks()
*/
class Playlist
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"channel:read", "playlist:read", "playlist:read:id", "day:read", "objective:read", "video:read"})
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity=Video::class, inversedBy="playlists")
* @Groups({"single_channel:read", "playlist:read", "playlist:read:videos", "playlist:write", "day:read", "homepage:read", "program_single_list", "objective:read", "objective:write", "objective_form_complete", "program:read", "program:write", "day:write", "channel:read"})
* @ApiSubresource(maxDepth=1)
*/
private $videos;
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
* @Groups({"playlist:read", "playlist:read:createdAt"})
*/
private $createdAt;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Gedmo\Timestampable(on="update")
* @Groups({"playlist:read", "playlist:read:updatedAt"})
*/
private $updatedAt;
/**
* @ORM\OneToMany(targetEntity=VideoLastValidate::class, mappedBy="playlist", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
*/
private $videoLastValidates;
/**
* @ORM\OneToMany(targetEntity=VideoLastSeen::class, mappedBy="playlist", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
*/
private $videoLastSeens;
/**
* @ORM\OneToMany(targetEntity=Channel::class, mappedBy="playlist", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
*/
private $channels;
/**
* @var int
* @Groups({"single_channel:read", "playlist:read", "day:read", "homepage:read"})
*/
public $activeVideoCount = 0;
/**
* @var string|null
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"video:read", "video_form_complete", "objective_form_complete", "playlist:read", "playlist:read:name", "playlist:write"})
*/
private $name = null;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="playlists")
* @Groups({"channel:read", "channel:read:user", "channel:write", "category:read", "search_engine", "playlist:read", "playlist:read:user"})
*/
private $user;
public function __construct()
{
$this->createdAt = new \DateTime();
$this->videos = new ArrayCollection();
$this->videoLastValidates = new ArrayCollection();
$this->videoLastSeens = new ArrayCollection();
$this->channels = new ArrayCollection();
}
public function __clone()
{
$this->id = null;
$this->videoLastValidates = new ArrayCollection();
$this->videoLastSeens = new ArrayCollection();
$this->channels = new ArrayCollection();
$this->createdAt = new \DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function setId(?int $id): self
{
$this->id = $id;
return $this;
}
/**
* @return Collection|Video[]
* @Groups({"objective_form_complete"})
*/
public function getVideos(): Collection
{
return $this->videos;
}
public function addVideo(Video $video): self
{
if (!$this->videos->contains($video)) {
$this->videos[] = $video;
}
return $this;
}
public function removeVideo(Video $video): self
{
$this->videos->removeElement($video);
return $this;
}
/**
* @Groups({"playlist:write"})
*/
public function setAddVideo(Video $video): self
{
$this->setUpdatedAt(new \DateTime('now'));
return $this->addVideo($video);
}
/**
* @Groups({"playlist:write"})
*/
public function setRemoveVideo(Video $video): self
{
$this->setUpdatedAt(new \DateTime('now'));
return $this->removeVideo($video);
}
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;
}
/**
* @param ArrayCollection|array $videos
* @return Playlist
*/
public function setVideos($videos): Playlist
{
if (is_array($videos)){
$videos = new ArrayCollection($videos);
}
$this->videos = $videos;
return $this;
}
/**
* Slices the videos list from offset to a limit
* @param int $limit Limit to which slice the videos
* @param int $offset Offset to start the slice
*/
public function limitTo(int $limit = 10, int $offset = 0)
{
$this->videos = new ArrayCollection($this->videos->slice($offset, $limit));
}
/**
* @ORM\PostLoad()
*/
public function updateActiveCount()
{
$criteria = Criteria::create()->andWhere(Criteria::expr()->eq('active', true));
$this->activeVideoCount = $this->videos->matching($criteria)->count();
}
/**
* @return string|null
*/
public function getName(): ?string
{
if(empty($this->name)) {
if($this->channels->count() > 0) {
$this->name = $this->channels->first()->getName();
}
}
return $this->name;
}
/**
* @param string|null $name
* @return Playlist
*/
public function setName(?string $name): Playlist
{
$this->name = $name;
return $this;
}
public static function buildFromArray(array $data): Playlist
{
$pl = new Playlist();
$pl->id = $data['id'];
$pl->createdAt = $data['createdAt'];
$pl->name = $data['name'];
return $pl;
}
/**
* @Groups({"channel:read", "day:read", "program:read", "video:read"})
*/
public function getStringifyTags()
{
$stringifyTags = [];
if(!empty($this->videos)) {
foreach($this->videos as $video) {
if($video->getActive() == 1 && !empty($video->getTvTags())) {
foreach($video->getTvTags() as $tvTag) {
if(!in_array($tvTag->__toString(), $stringifyTags) && $tvTag->getActive() == 1) {
$stringifyTags[] = $tvTag->__toString();
}
}
}
}
return implode("", array_unique($stringifyTags, SORT_STRING));
}
return null;
}
/**
* @return Collection|VideoLastValidate[]
*/
public function getVideoLastValidates(): Collection
{
return $this->videoLastValidates;
}
public function addVideoLastValidate(VideoLastValidate $videoLastValidate): self
{
if (!$this->videoLastValidates->contains($videoLastValidate)) {
$this->videoLastValidates[] = $videoLastValidate;
$videoLastValidate->setPlaylist($this);
}
return $this;
}
public function removeVideoLastValidate(VideoLastValidate $videoLastValidate): self
{
if ($this->videoLastValidates->removeElement($videoLastValidate)) {
// set the owning side to null (unless already changed)
if ($videoLastValidate->getPlaylist() === $this) {
$videoLastValidate->setPlaylist(null);
}
}
return $this;
}
/**
* @return Collection|VideoLastSeen[]
*/
public function getVideoLastSeens(): Collection
{
return $this->videoLastSeens;
}
public function addVideoLastSeen(VideoLastSeen $videoLastSeen): self
{
if (!$this->videoLastSeens->contains($videoLastSeen)) {
$this->videoLastSeens[] = $videoLastSeen;
$videoLastSeen->setPlaylist($this);
}
return $this;
}
public function removeVideoLastSeen(VideoLastSeen $videoLastSeen): self
{
if ($this->videoLastSeens->removeElement($videoLastSeen)) {
// set the owning side to null (unless already changed)
if ($videoLastSeen->getPlaylist() === $this) {
$videoLastSeen->setPlaylist(null);
}
}
return $this;
}
/**
* @return Collection|Channel[]
*/
public function getChannels(): Collection
{
return $this->channels;
}
public function addChannel(Channel $channel): self
{
if (!$this->channels->contains($channel)) {
$this->channels[] = $channel;
$channel->setPlaylist($this);
}
return $this;
}
public function removeChannel(Channel $channel): self
{
if ($this->channels->removeElement($channel)) {
// set the owning side to null (unless already changed)
if ($channel->getPlaylist() === $this) {
$channel->setPlaylist(null);
}
}
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}