<?php
namespace App\Entity\Profile\Confirmation;
use App\Entity\Profile\Profile;
use Carbon\CarbonImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\PersistentCollection;
#[ORM\Table(name: 'profile_confirmation_requests')]
#[ORM\Entity]
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'type', type: 'string', length: 12)]
#[ORM\DiscriminatorMap(['approval' => ApprovalRequest::class, 'moderation' => ModerationRequest::class])]
abstract class ConfirmationRequest
{
/**
* Ожидает завершения системных процессов, чтобы перейти в статус WAITING
*/
public const STATUS_PROCESSING = 'PROCESSING';
/**
* Ожидает действий модератора
*/
public const STATUS_WAITING = 'WAITING';
public const STATUS_REJECTED = 'REJECTED';
public const STATUS_APPROVED = 'APPROVED';
#[ORM\Id]
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\GeneratedValue(strategy: 'AUTO')]
protected int $id;
#[ORM\JoinColumn(name: 'profile_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: Profile::class)]
protected Profile $profile;
#[ORM\Column(type: 'string', columnDefinition: "ENUM('PROCESSING', 'WAITING', 'REJECTED', 'APPROVED')")]
protected string $status;
#[ORM\Column(type: 'integer', nullable: true)]
protected ?int $reason;
#[ORM\Column(type: 'string', nullable: true)]
protected ?string $comment;
#[ORM\Column(type: 'json', nullable: true)]
protected ?array $data;
/** @var Photo[] */
#[ORM\OneToMany(targetEntity: Photo::class, mappedBy: 'confirmationRequest', cascade: ['all'], orphanRemoval: true)]
protected Collection $photos;
/** @var PersistentCollection|Video[] */
#[ORM\OneToMany(targetEntity: Video::class, mappedBy: 'confirmationRequest', cascade: ['all'], orphanRemoval: true)]
protected Collection $videos;
#[ORM\Column(name: 'updated_at', type: 'datetimetz_immutable', nullable: true)]
protected ?\DateTimeImmutable $updatedAt;
public function __construct(Profile $profile)
{
$this->profile = $profile;
$this->updatedAt = CarbonImmutable::now();
$this->status = self::STATUS_WAITING;
$this->photos = new ArrayCollection();
$this->videos = new ArrayCollection();
$this->data = null;
}
public function checkProcessingFiles(): void
{
if ($this->profile->hasFilesInProcess()) {
$this->status = self::STATUS_PROCESSING;
}
}
public function getId(): int
{
return $this->id;
}
public function getProfile(): Profile
{
return $this->profile;
}
public function setProfile(Profile $profile): void
{
$this->profile = $profile;
}
public function getStatus(): string
{
return $this->status;
}
public function setStatus(string $status): void
{
$this->status = $status;
}
public function getUpdatedAt(): \DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): void
{
$this->updatedAt = $updatedAt;
}
public function finishProcessing(): void
{
if (self::STATUS_PROCESSING === $this->status) {
$this->status = self::STATUS_WAITING;
}
}
public function isWaiting(): bool
{
return $this->status === self::STATUS_WAITING || $this->status === self::STATUS_PROCESSING;
}
public function isApproved(): bool
{
return $this->status == self::STATUS_APPROVED;
}
public function isRejected(): bool
{
return $this->status == self::STATUS_REJECTED;
}
// public function isApprovalRejected(): bool
// {
// return $this->approvalRequest && $this->approvalRequest->getStatus() == ApprovalRequest::STATUS_REJECTED;
// }
public function approve(): void
{
$this->status = self::STATUS_APPROVED;
$this->updatedAt = CarbonImmutable::now();
}
public function reject(?int $reason = null, ?string $comment = null): void
{
$this->status = self::STATUS_REJECTED;
$this->updatedAt = CarbonImmutable::now();
if($reason) {
$this->reason = $reason;
if ($comment)
$this->comment = $comment;
}
}
public function setReason(int $reason): void
{
$this->reason = $reason;
}
public function setComment(?string $comment): void
{
$this->comment = $comment;
}
public function getPhoto(): ?Photo
{
return $this->photos->count() ? $this->photos->first() : null;
}
public function setPhoto(Photo $photo): void
{
$this->photos->clear();
$this->photos->add($photo);
}
public function getVideo(): ?Video
{
return $this->videos->count() ? $this->videos->first() : null;
}
public function setVideo(Video $video): void
{
$this->videos->clear();
$this->videos->add($video);
}
public function isMediaProcessed(): bool
{
if (self::STATUS_PROCESSING === $this->status) {
return false;
}
if (null === $this->getVideo()) {
return true;
}
return null !== $this->getVideo()->getPreviewPath();
}
public function isProfileMediaProcessed(): bool
{
if (self::STATUS_PROCESSING === $this->status) {
return false;
}
foreach ($this->profile->getVideos() as $video) {
if (null === $video->getPreviewPath()) {
return false;
}
}
return true;
}
public function getData(): ?array
{
return $this->data;
}
public function setData(?array $data): void
{
$this->data = $data;
}
}