Skip to content

Commit

Permalink
Talk with multiple speakers (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
loic425 authored Oct 2, 2024
2 parents e91a1df + 5c91506 commit 945e731
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 59 deletions.
55 changes: 38 additions & 17 deletions app/Entity/Talk.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use App\Form\TalkType;
use App\Grid\TalkGrid;
use App\Repository\TalkRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Resource\Metadata\AsResource;
Expand All @@ -26,6 +28,7 @@
use Sylius\Resource\Metadata\Index;
use Sylius\Resource\Metadata\Update;
use Sylius\Resource\Model\ResourceInterface;
use Symfony\Component\Validator\Constraints\NotBlank;

#[ORM\Entity(repositoryClass: TalkRepository::class)]
#[AsResource(
Expand All @@ -49,19 +52,18 @@ class Talk implements ResourceInterface
private ?int $id = null;

#[ORM\Column(length: 255)]
#[NotBlank]
private ?string $title = null;

#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $description = null;

#[ORM\ManyToOne(inversedBy: 'talks')]
#[ORM\JoinColumn(nullable: false)]
private ?Speaker $speaker = null;

#[ORM\Column]
#[NotBlank]
private ?\DateTimeImmutable $startsAt = null;

#[ORM\Column]
#[NotBlank]
private ?\DateTimeImmutable $endsAt = null;

#[ORM\Column(enumType: Track::class)]
Expand All @@ -71,6 +73,15 @@ class Talk implements ResourceInterface
#[ORM\JoinColumn(nullable: false)]
private ?Conference $conference = null;

/** @var Collection<int, Speaker> */
#[ORM\ManyToMany(targetEntity: Speaker::class)]
private Collection $speakers;

public function __construct()
{
$this->speakers = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
Expand All @@ -81,7 +92,7 @@ public function getTitle(): ?string
return $this->title;
}

public function setTitle(string $title): void
public function setTitle(?string $title): void
{
$this->title = $title;
}
Expand All @@ -96,22 +107,12 @@ public function setDescription(?string $description): void
$this->description = $description;
}

public function getSpeaker(): ?Speaker
{
return $this->speaker;
}

public function setSpeaker(?Speaker $speaker): void
{
$this->speaker = $speaker;
}

public function getStartsAt(): ?\DateTimeImmutable
{
return $this->startsAt;
}

public function setStartsAt(\DateTimeImmutable $startsAt): void
public function setStartsAt(?\DateTimeImmutable $startsAt): void
{
$this->startsAt = $startsAt;
}
Expand All @@ -121,7 +122,7 @@ public function getEndsAt(): ?\DateTimeImmutable
return $this->endsAt;
}

public function setEndsAt(\DateTimeImmutable $endsAt): void
public function setEndsAt(?\DateTimeImmutable $endsAt): void
{
$this->endsAt = $endsAt;
}
Expand All @@ -145,4 +146,24 @@ public function setConference(?Conference $conference): void
{
$this->conference = $conference;
}

/**
* @return Collection<int, Speaker>
*/
public function getSpeakers(): Collection
{
return $this->speakers;
}

public function addSpeaker(Speaker $speaker): void
{
if (!$this->speakers->contains($speaker)) {
$this->speakers->add($speaker);
}
}

public function removeSpeaker(Speaker $speaker): void
{
$this->speakers->removeElement($speaker);
}
}
9 changes: 5 additions & 4 deletions app/Factory/TalkFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ public function withDescription(string $description): self
return $this->with(['description' => $description]);
}

/** @param Speaker|Proxy<Speaker> $speaker */
public function withSpeaker(Proxy|Speaker $speaker): self
/**
* @param Proxy<Speaker>|Speaker ...$speakers
*/
public function withSpeakers(Proxy|Speaker ...$speakers): self
{
return $this->with(['speaker' => $speaker]);
return $this->with(['speakers' => $speakers]);
}

public function withStartingDate(\DateTimeImmutable $startsAt): self
Expand Down Expand Up @@ -73,7 +75,6 @@ public function withConference(Proxy|Conference $conference): self
protected function defaults(): array|callable
{
return [
'speaker' => SpeakerFactory::new(),
'title' => self::faker()->text(255),
'startsAt' => \DateTimeImmutable::createFromMutable(self::faker()->dateTime()),
'endsAt' => \DateTimeImmutable::createFromMutable(self::faker()->dateTime()),
Expand Down
28 changes: 27 additions & 1 deletion app/Form/TalkType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,45 @@

namespace App\Form;

use App\Entity\Conference;
use App\Entity\Talk;
use App\Enum\Track;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\LiveComponent\Form\Type\LiveCollectionType;

class TalkType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title')
->add('speaker', SpeakerAutocompleteType::class)
->add('conference', EntityType::class, [
'class' => Conference::class,
'choice_label' => 'name',
'placeholder' => 'Select a conference',
])
->add('track', EnumType::class, [
'class' => Track::class,
])
->add('speakers', LiveCollectionType::class, [
'entry_type' => SpeakerAutocompleteType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'label' => 'app.ui.speakers',
])
->add('description')
->add('startsAt', DateTimeType::class, [
'widget' => 'single_text',
])
->add('endsAt', DateTimeType::class, [
'widget' => 'single_text',
])
;
}

Expand Down
19 changes: 9 additions & 10 deletions app/Grid/TalkGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void
->addFormOption('choice_label', 'name'),
)
->addFilter(
EntityFilter::create('speaker', Speaker::class)
EntityFilter::create(name: 'speaker', resourceClass: Speaker::class, fields: ['speakers.id'])
->setLabel('app.ui.speaker')
->addFormOption('choice_label', 'fullName'),
)
Expand All @@ -67,19 +67,18 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void
->setLabel('app.ui.track'),
)
->addField(
TwigField::create('avatar', 'speaker/grid/field/image.html.twig')
->setPath('speaker'),
TwigField::create('avatar', 'talk/grid/field/images.html.twig')
->setPath('speakers')
->setLabel('app.ui.avatar'),
)
->addField(
StringField::create('title')
->setLabel('Title')
->setSortable(true),
TwigField::create('speakers', 'talk/grid/field/speakers.html.twig')
->setLabel('app.ui.speakers'),
)
->addField(
StringField::create('speaker')
->setLabel('app.ui.speaker')
->setPath('speaker.fullName')
->setSortable(true, 'speaker.firstName'),
StringField::create('title')
->setLabel('app.ui.title')
->setSortable(true),
)
->addField(
DateTimeField::create('startsAt', 'Y-m-d H:i')
Expand Down
Loading

0 comments on commit 945e731

Please sign in to comment.