<?php
namespace App\Domain\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use App\Application\ApiResources\State\Processor\Comment\CommentDeleteProcessor;
use App\Application\ApiResources\State\Processor\Comment\CommentInputProcessor;
use App\Application\ApiResources\State\Processor\Comment\CommentsValidateProcessor;
use App\Application\ApiResources\State\Processor\Comment\CommentUpdateProcessor;
use App\Application\ApiResources\State\Processor\Comment\CommentValidateProcessor;
use App\Application\ApiResources\State\Provider\GetUncertifiedCommentProvider;
use App\Application\Controller\Api\Comment\GetLastCommunityAction;
use App\Application\Controller\Api\Comment\GetWithRevisionAction;
use App\Application\Dto\Comment\CommentInput;
use App\Application\Dto\Comment\CommentsValidateInput;
use App\Domain\Entity\Behavior\Identifiable;
use App\Domain\Entity\Translation\CommentTranslation;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\SoftDeleteable\Traits\SoftDeleteable;
use Gedmo\Timestampable\Traits\Timestampable;
use Locastic\ApiPlatformTranslationBundle\Model\AbstractTranslatable;
use Locastic\ApiPlatformTranslationBundle\Model\TranslationInterface;
/**
* Class Comment
*
* @package App\Domain\Entity
*/
#[ApiResource(
operations: [
new Delete(processor: CommentDeleteProcessor::class),
new GetCollection(uriTemplate: '/comments/with_revision', controller: GetWithRevisionAction::class),
new GetCollection(uriTemplate: '/comments/last_community', controller: GetLastCommunityAction::class),
new GetCollection(
filters: [
'comment.search_filter',
'comment.exists_filter',
'soft_delete_filter',
'comment.order_filter',
'comment.null_filter',
],
),
new GetCollection(
uriTemplate: '/comments/uncertified_list',
provider: GetUncertifiedCommentProvider::class
),
new Get(),
new Post(
normalizationContext: ['groups' => ['translations']],
input: CommentInput::class,
processor: CommentInputProcessor::class
),
new Put(normalizationContext: ['groups' => ['translations']], processor: CommentUpdateProcessor::class),
new Put(uriTemplate: '/comments/{uuid}/validate', processor: CommentValidateProcessor::class),
new Post(
uriTemplate: '/comments/validate',
input: CommentsValidateInput::class,
processor: CommentsValidateProcessor::class,
deserialize: true,
inputFormats: ['json' => ['application/json', 'application/ld+json']],
outputFormats: ['json' => ['application/json', 'application/ld+json']],
),
],
normalizationContext: ['groups' => ['comment_read']],
denormalizationContext: ['groups' => ['comment_write']],
filters: ['translation.groups'],
order: ['createdAt' => 'DESC'],
)]
#[ApiResource(
uriTemplate: '/people/{uuid}/comments',
operations: [
new GetCollection(normalizationContext: ['groups' => 'comment_read']),
],
uriVariables: [
'uuid' => new Link(toProperty: 'author', fromClass: Person::class),
]
)]
abstract class Comment extends AbstractTranslatable
{
use Identifiable;
use SoftDeleteable;
use Timestampable;
public const COMMENT_ACCEPTED = 'accepted';
public const COMMENT_NEW = 'new';
public const COMMENT_REFUSED = 'refused';
private Collection $children;
public ?string $remoteId = null;
/**
* @param Person $author
* @param Locale|null $authorLocale
* @param string $status
* @param int $notation
* @param Comment|null $parent
* @param DateTime|null $zhistUpdate
*/
public function __construct(
public Person $author,
public Locale | null $authorLocale,
public string $status = self::COMMENT_NEW,
public int $notation = 0,
public Comment | null $parent = null,
public ?DateTime $zhistUpdate = null,
public ?DateTime $lastUserUpdate = null,
) {
parent::__construct();
$this->children = new ArrayCollection();
}
public function createTranslation(): TranslationInterface
{
return new CommentTranslation();
}
public function getTranslationType($locale = null): CommentTranslation
{
return $this->getTranslation($locale);
}
public function getValue(): ?string
{
return $this->getTranslationType()->getValue();
}
public function setValue(?string $value): void
{
$this->getTranslationType()->setValue($value);
}
/**
* @return Collection
*/
public function getChildren(): Collection
{
return $this->children->filter(fn(Comment $child) => $child->status === self::COMMENT_ACCEPTED && $child->deletedAt === null);
}
/**
* @param Collection $children
*/
public function setChildren(Collection $children): void
{
$this->children = $children;
}
/**
* @param Comment $child
*
* @return void
*/
public function addChild(Comment $child): void
{
if ($this->children->contains($child)) {
return;
}
$this->children->add($child);
}
/**
* @param Comment $child
*
* @return void
*/
public function removeChild(Comment $child): void
{
if (!$this->children->contains($child)) {
return;
}
$this->children->removeElement($child);
}
public function getDefaultValue(): string
{
/** @var CommentTranslation $translation */
$translation = $this->getTranslation($this->authorLocale->alpha2);
return $translation->getValue();
}
public function setLastUserUpdate(): void
{
$this->lastUserUpdate = new DateTime();
}
}