feat : add collaborators ManyToMany on Task entity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||||||
denormalizationContext: ['groups' => ['task:write']],
|
denormalizationContext: ['groups' => ['task:write']],
|
||||||
order: ['id' => 'DESC'],
|
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(DateFilter::class, properties: ['scheduledStart', 'scheduledEnd', 'deadline'])]
|
||||||
#[ApiFilter(BooleanFilter::class, properties: ['archived', 'syncToCalendar'])]
|
#[ApiFilter(BooleanFilter::class, properties: ['archived', 'syncToCalendar'])]
|
||||||
#[ApiFilter(OrderFilter::class, properties: ['scheduledStart', 'deadline'])]
|
#[ApiFilter(OrderFilter::class, properties: ['scheduledStart', 'deadline'])]
|
||||||
@@ -85,6 +85,16 @@ class Task
|
|||||||
#[Groups(['task:read', 'task:write'])]
|
#[Groups(['task:read', 'task:write'])]
|
||||||
private ?User $assignee = null;
|
private ?User $assignee = null;
|
||||||
|
|
||||||
|
/** @var Collection<int, User> */
|
||||||
|
#[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\ManyToOne(targetEntity: TaskGroup::class)]
|
||||||
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
|
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
|
||||||
#[Groups(['task:read', 'task:write'])]
|
#[Groups(['task:read', 'task:write'])]
|
||||||
@@ -152,8 +162,9 @@ class Task
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->tags = new ArrayCollection();
|
$this->tags = new ArrayCollection();
|
||||||
$this->documents = new ArrayCollection();
|
$this->documents = new ArrayCollection();
|
||||||
|
$this->collaborators = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
@@ -245,6 +256,28 @@ class Task
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return Collection<int, User> */
|
||||||
|
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
|
public function getGroup(): ?TaskGroup
|
||||||
{
|
{
|
||||||
return $this->group;
|
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()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user