diff --git a/src/Entity/Task.php b/src/Entity/Task.php index 320468f..639b929 100644 --- a/src/Entity/Task.php +++ b/src/Entity/Task.php @@ -38,7 +38,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; denormalizationContext: ['groups' => ['task:write']], order: ['id' => 'DESC'], )] -#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact', 'group' => 'exact', 'assignee' => 'exact', 'priority' => 'exact', 'effort' => 'exact', 'tags' => 'exact', 'status' => 'exact'])] +#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact', 'group' => 'exact', 'assignee' => 'exact', 'collaborators' => 'exact', 'priority' => 'exact', 'effort' => 'exact', 'tags' => 'exact', 'status' => 'exact'])] #[ApiFilter(DateFilter::class, properties: ['scheduledStart', 'scheduledEnd', 'deadline'])] #[ApiFilter(BooleanFilter::class, properties: ['archived', 'syncToCalendar'])] #[ApiFilter(OrderFilter::class, properties: ['scheduledStart', 'deadline'])] @@ -85,6 +85,16 @@ class Task #[Groups(['task:read', 'task:write'])] private ?User $assignee = null; + /** @var Collection */ + #[ORM\ManyToMany(targetEntity: User::class)] + #[ORM\JoinTable( + name: 'task_collaborator', + joinColumns: [new ORM\JoinColumn(name: 'task_id', referencedColumnName: 'id', onDelete: 'CASCADE')], + inverseJoinColumns: [new ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE')], + )] + #[Groups(['task:read', 'task:write'])] + private Collection $collaborators; + #[ORM\ManyToOne(targetEntity: TaskGroup::class)] #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')] #[Groups(['task:read', 'task:write'])] @@ -152,8 +162,9 @@ class Task public function __construct() { - $this->tags = new ArrayCollection(); - $this->documents = new ArrayCollection(); + $this->tags = new ArrayCollection(); + $this->documents = new ArrayCollection(); + $this->collaborators = new ArrayCollection(); } public function getId(): ?int @@ -245,6 +256,28 @@ class Task return $this; } + /** @return Collection */ + public function getCollaborators(): Collection + { + return $this->collaborators; + } + + public function addCollaborator(User $user): static + { + if (!$this->collaborators->contains($user)) { + $this->collaborators->add($user); + } + + return $this; + } + + public function removeCollaborator(User $user): static + { + $this->collaborators->removeElement($user); + + return $this; + } + public function getGroup(): ?TaskGroup { return $this->group; @@ -434,4 +467,15 @@ class Task ; } } + + #[Assert\Callback] + public function validateCollaborators(ExecutionContextInterface $context): void + { + if (null !== $this->assignee && $this->collaborators->contains($this->assignee)) { + $context->buildViolation('The assignee cannot also be a collaborator.') + ->atPath('collaborators') + ->addViolation() + ; + } + } }