Skip to content

Commit

Permalink
Talk with multiple speakers
Browse files Browse the repository at this point in the history
  • Loading branch information
loic425 committed Oct 2, 2024
1 parent 1723b52 commit 683bb0b
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 59 deletions.
18 changes: 1 addition & 17 deletions app/Entity/Talk.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ class Talk implements ResourceInterface
#[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]
private ?\DateTimeImmutable $startsAt = null;

Expand All @@ -73,9 +69,7 @@ class Talk implements ResourceInterface
#[ORM\JoinColumn(nullable: false)]
private ?Conference $conference = null;

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

Expand Down Expand Up @@ -109,16 +103,6 @@ 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;
Expand Down
7 changes: 0 additions & 7 deletions app/Factory/TalkFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ public function withDescription(string $description): self
return $this->with(['description' => $description]);
}

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

/**
* @param Proxy<Speaker>|Speaker ...$speakers
*/
Expand Down Expand Up @@ -81,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
17 changes: 8 additions & 9 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,20 +67,19 @@ 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(
TwigField::create('speakers', 'talk/grid/field/speakers.html.twig')
->setLabel('app.ui.speakers'),
)
->addField(
StringField::create('title')
->setLabel('Title')
->setSortable(true),
)
->addField(
StringField::create('speaker')
->setLabel('app.ui.speaker')
->setPath('speaker.fullName')
->setSortable(true, 'speaker.firstName'),
)
->addField(
DateTimeField::create('startsAt', 'Y-m-d H:i')
->setLabel('app.ui.starts_at')
Expand Down
12 changes: 12 additions & 0 deletions app/Repository/TalkRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use App\Entity\Talk;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

/**
Expand All @@ -26,4 +27,15 @@ public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Talk::class);
}

public function createListQueryBuilder(): QueryBuilder
{
$queryBuilder = $this->createQueryBuilder('o');

$queryBuilder
->addSelect('speaker')
->leftJoin('o.speakers', 'speaker');

return $queryBuilder;
}
}
50 changes: 27 additions & 23 deletions app/Story/DefaultSyliusCon2024TalksStory.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private function createBizTalks(): void
{
TalkFactory::new()
->withTitle('The Missing Piece in the Developer\'s Toolkit: Communication')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Stéphane', 'lastName' => 'Decock']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Stéphane', 'lastName' => 'Decock']))
->withDescription(
<<<'TEXT'
This talk will explore the vital role of communication in software development. Stéphane will discuss how effective communication can bridge the gap between developers and stakeholders, reduce misunderstandings, and lead to more successful projects. He will also provide techniques to help developers articulate complex ideas clearly and understand stakeholder needs better.
Expand All @@ -47,7 +47,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('TBA')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Hélèna', 'lastName' => 'Gravelier']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Hélèna', 'lastName' => 'Gravelier']))
->withDescription(
<<<'TEXT'
Details of this presentation will be announced soon.
Expand All @@ -62,7 +62,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('TBA')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Przemysław', 'lastName' => 'Połeć']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Przemysław', 'lastName' => 'Połeć']))
->withDescription(
<<<'TEXT'
Details of this presentation will be announced soon.
Expand All @@ -77,7 +77,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('Transforming the Retail Industry with Sylius')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Zrinka', 'lastName' => 'Dedic']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Zrinka', 'lastName' => 'Dedic']))
->withDescription(
<<<'TEXT'
Zrinka will share how Locastic utilized Sylius to transform the retail operations of Tommy.hr. The presentation will cover the specific strategies and changes implemented using Sylius to improve efficiency and operational effectiveness in the retail sector.
Expand All @@ -92,7 +92,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('Building a Sustainable Accessibility Program for Your Team')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Kuba', 'lastName' => 'Zwoliński']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Kuba', 'lastName' => 'Zwoliński']))
->withDescription(
<<<'TEXT'
Kuba will outline the key elements needed to create a sustainable accessibility program within an organization. He will focus on developing an accessibility culture, integrating accessibility into your workflows from the beginning, and preparing for upcoming European regulations like the European Accessibility Act.
Expand All @@ -107,7 +107,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('Multiple Webshops with Case-Specific Sales Processes on One Sylius Instance - A Case Study')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Gregor', 'lastName' => 'Šink']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Gregor', 'lastName' => 'Šink']))
->withDescription(
<<<'TEXT'
Gregor will present a case study of DZS, a Slovenian publishing house, which integrated multiple webshops into a single Sylius instance. The talk will cover how this consolidation catered to different customer needs (B2C, B2B, CMS) under one platform, providing a unique experience for each user while reducing operating expenses.
Expand All @@ -122,7 +122,7 @@ private function createBizTalks(): void

TalkFactory::new()
->withTitle('When Sylius Meets Beer: A Refresh That’s Brewing Up a Storm')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Julien', 'lastName' => 'Jacottet']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Julien', 'lastName' => 'Jacottet']))
->withDescription(
<<<'TEXT'
Julien, CTO of Mezcalito, will take you through the journey of Une Petite Mousse, a popular online beer shop, and their successful transition from an internal solution to Sylius. He will share the challenges they overcame, the innovative solutions they developed, and how Sylius helped brew up tangible, sparkling results.
Expand All @@ -140,7 +140,7 @@ private function createTechOneTalks(): void
{
TalkFactory::new()
->withTitle('Create World-Class Sylius Plugins')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Joachim', 'lastName' => 'Løvgaard']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Joachim', 'lastName' => 'Løvgaard']))
->withDescription(
<<<'TEXT'
Joachim will share his extensive experience in creating Sylius plugins and bundles. He will discuss the best practices for plugin development, focusing on aspects such as code quality, dependency management, and optimizing the developer experience to build effective and maintainable plugins.
Expand All @@ -155,7 +155,7 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Sylius Beyond E-commerce: Building the Perfect WordPress Competitor')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Jacques', 'lastName' => 'Bodin-Hullin']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Jacques', 'lastName' => 'Bodin-Hullin']))
->withDescription(
<<<'TEXT'
Jacques will introduce the NoCommerce plugin, which transforms Sylius into a robust framework for building a variety of websites beyond e-commerce. He will explain how this plugin can make Sylius a versatile alternative to WordPress for non-commercial sites, detailing the integration process and unique benefits.
Expand All @@ -170,7 +170,7 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Sylius Payment Overview and Future')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Francis', 'lastName' => 'Hilaire']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Francis', 'lastName' => 'Hilaire']))
->withDescription(
<<<'TEXT'
Francis will provide a comprehensive overview of the Sylius payment system, focusing on its history and upcoming developments in Sylius 2.0. He will discuss the challenges faced in building the system and how new features will improve payment handling and integration.
Expand All @@ -185,8 +185,10 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Adapting Price Calculation to B2B Needs')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Luca', 'lastName' => 'Gallinari']))
//->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Manuele', 'lastName' => 'Menozzi']))
->withSpeakers(
SpeakerFactory::findOrCreate(['firstName' => 'Luca', 'lastName' => 'Gallinari']),
SpeakerFactory::findOrCreate(['firstName' => 'Manuele', 'lastName' => 'Menozzi']),
)
->withDescription(
<<<'TEXT'
Luca and Manuele will explain how to customize the Sylius Price Calculator for complex B2B pricing models. The talk will cover practical examples of how to implement these changes and ensure accurate pricing through automated testing.
Expand All @@ -201,7 +203,7 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Beyond One-Size-Fits-All: Unlocking User Value with Profilation and Adaptable Architecture')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Viorel', 'lastName' => 'Tudor']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Viorel', 'lastName' => 'Tudor']))
->withDescription(
<<<'TEXT'
Viorel will discuss how Freshful leverages Sylius to create personalized, consumer-centric solutions. The presentation will cover how detailed user profiling and a modular architecture allow for tailored e-grocery experiences that enhance customer satisfaction and engagement.
Expand All @@ -216,8 +218,10 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Handling Background Processing in Sylius')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Łukasz', 'lastName' => 'Chruściel']))
//->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Mateusz', 'lastName' => 'Zalewski']))
->withSpeakers(
SpeakerFactory::findOrCreate(['firstName' => 'Łukasz', 'lastName' => 'Chruściel']),
SpeakerFactory::findOrCreate(['firstName' => 'Mateusz', 'lastName' => 'Zalewski']),
)
->withDescription(
<<<'TEXT'
Łukasz and Mateusz will explore different methods for managing background tasks in Sylius applications. They will cover basic techniques using Symfony console commands, more advanced approaches with Symfony Messenger, and sophisticated strategies for high availability and fault tolerance.
Expand All @@ -232,7 +236,7 @@ private function createTechOneTalks(): void

TalkFactory::new()
->withTitle('Building a Semantic Search Experience Using PHP and Meilisearch')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Guillaume', 'lastName' => 'Loulier']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Guillaume', 'lastName' => 'Loulier']))
->withDescription(
<<<'TEXT'
Guillaume will demonstrate how to build a semantic search experience using PHP and Meilisearch. He will cover how to leverage recent advancements in machine learning and search engine technology to improve search accuracy and user experience in your applications.
Expand All @@ -250,7 +254,7 @@ private function createTechTwoTalks(): void
{
TalkFactory::new()
->withTitle('Boost Your Sylius Frontend with Hotwire, aka Symfony UX')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Loïc', 'lastName' => 'Caillieux']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Loïc', 'lastName' => 'Caillieux']))
->withDescription(
<<<'TEXT'
Loïc will showcase how to enhance the frontend of your Sylius application using Hotwire and Symfony UX. He will provide live examples of how these tools can improve the user interface and experience, focusing on making the frontend more dynamic and responsive.
Expand All @@ -265,7 +269,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('Admin Panel (R)evolution for Your Symfony Projects')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Loïc', 'lastName' => 'Frémont']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Loïc', 'lastName' => 'Frémont']))
->withDescription(
<<<'TEXT'
Loïc will cover the evolution of the Sylius admin panel, from its initial use of Bootstrap to the current integration with tools like the Sylius Grid component and Twig Hooks. He will discuss how these changes improve the admin panel's functionality and how they can be applied to any Symfony project.
Expand All @@ -279,7 +283,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('Prepping for Black Friday: Improve, Scale, and Stress Test Your Sylius App')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Thomas', 'lastName' => 'di Luccio']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Thomas', 'lastName' => 'di Luccio']))
->withDescription(
<<<'TEXT'
Thomas will provide strategies for preparing your Sylius application for peak traffic during events like Black Friday. He will explain how to use tools like Blackfire and Platform.sh for performance optimization and load testing to ensure your app remains stable under high demand.
Expand All @@ -294,7 +298,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('Crafting an Open Source Product Discovery Solution')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Romain', 'lastName' => 'Ruaud']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Romain', 'lastName' => 'Ruaud']))
->withDescription(
<<<'TEXT'
Romain will share the story behind the inception and development of Gally, an open-source search engine solution for product discovery. You’ll learn how to build a REST/GraphQL layer on top of Elasticsearch using API Platform and Symfony. Romain will cover key technical principles, such as Elasticsearch index abstraction, automatic mapping computation, and GraphQL stitching. Additionally, you'll discover how Gally can be leveraged in a Composable Commerce approach, including various architectural use cases like Headless Sylius, Headful Sylius, and external applications, such as vendor tablets.
Expand All @@ -309,7 +313,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('TBA')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Kévin', 'lastName' => 'Dunglas']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Kévin', 'lastName' => 'Dunglas']))
->withDescription(
<<<'TEXT'
Details of this presentation will be announced soon.
Expand All @@ -324,7 +328,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('Simplifying Sylius Containerization with DDEV')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Stephan', 'lastName' => 'Hochdörfer']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Stephan', 'lastName' => 'Hochdörfer']))
->withDescription(
<<<'TEXT'
Stephan will demonstrate how DDEV simplifies the use of Docker and Docker Compose for Sylius applications. The talk will include a step-by-step guide on installing and integrating DDEV into a Sylius project and how to extend its capabilities for better development workflows.
Expand All @@ -339,7 +343,7 @@ private function createTechTwoTalks(): void

TalkFactory::new()
->withTitle('Developer Docs: The write way to streamline project')
->withSpeaker(SpeakerFactory::findOrCreate(['firstName' => 'Ksenia', 'lastName' => 'Zvereva']))
->withSpeakers(SpeakerFactory::findOrCreate(['firstName' => 'Ksenia', 'lastName' => 'Zvereva']))
->withDescription(
<<<'TEXT'
Ksenia will share her approach to improving developer documentation. She will offer tips on how clear and effective documentation can streamline project development, enhance collaboration, and improve overall project outcomes.
Expand Down
1 change: 1 addition & 0 deletions templates/talk/grid/field/images.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include 'speaker/grid/field/image.html.twig' with {data: data[0]|default(null)} only %}
Loading

0 comments on commit 683bb0b

Please sign in to comment.