Skip to content

Commit

Permalink
feat(podcast): add guests collection
Browse files Browse the repository at this point in the history
  • Loading branch information
bernard-ng committed Oct 28, 2023
1 parent 76a4476 commit e67472b
Show file tree
Hide file tree
Showing 18 changed files with 446 additions and 363 deletions.
35 changes: 35 additions & 0 deletions migrations/Version20231028005726.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Class Version20231028005726.
*
* @author bernard-ng <[email protected]>
*/
final class Version20231028005726 extends AbstractMigration
{
public function getDescription(): string
{
return 'add podcast episode guests table';
}

public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE content_podcast_episode_guests (episode_id BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid)\', guest_id BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid)\', INDEX IDX_363E5AB6362B62A0 (episode_id), INDEX IDX_363E5AB69A4AA658 (guest_id), PRIMARY KEY(episode_id, guest_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE content_podcast_episode_guests ADD CONSTRAINT FK_363E5AB6362B62A0 FOREIGN KEY (episode_id) REFERENCES content_podcast_episode (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE content_podcast_episode_guests ADD CONSTRAINT FK_363E5AB69A4AA658 FOREIGN KEY (guest_id) REFERENCES user (id) ON DELETE CASCADE');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE content_podcast_episode_guests DROP FOREIGN KEY FK_363E5AB6362B62A0');
$this->addSql('ALTER TABLE content_podcast_episode_guests DROP FOREIGN KEY FK_363E5AB69A4AA658');
$this->addSql('DROP TABLE content_podcast_episode_guests');
}
}
465 changes: 204 additions & 261 deletions public/sw.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Application\Content\Command\Podcast;

use Application\Content\Command\AbstractContentCommand;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Domain\Content\Entity\Podcast\Season;
use Domain\Content\Enum\ContentType;
use Domain\Content\Enum\EpisodeType;
Expand All @@ -24,6 +26,7 @@ public function __construct(
#[Assert\GreaterThanOrEqual(1)] public ?int $episode_number = null,
public EpisodeType $episode_type = EpisodeType::FULL,
public ContentType $content_type = ContentType::PODCAST,
public Collection $guests = new ArrayCollection()
) {
}
}
10 changes: 8 additions & 2 deletions src/Application/Content/Command/Podcast/UpdateEpisodeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

use Application\Content\Command\AbstractContentCommand;
use Devscast\Bundle\DddBundle\Application\Mapper;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Domain\Content\Entity\Podcast\Episode;
use Domain\Content\Entity\Podcast\Season;
use Domain\Content\Enum\ContentType;
use Domain\Content\Enum\EpisodeType;
use Symfony\Component\HttpFoundation\File\File;

/**
Expand All @@ -18,13 +21,16 @@
*/
final class UpdateEpisodeCommand extends AbstractContentCommand
{
public ContentType $content_type = ContentType::PODCAST;
public EpisodeType $episode_type = EpisodeType::FULL;

public function __construct(
public Episode $_entity,
public ?Season $season = null,
public ?File $audio_file = null,
public ?int $episode_number = null,
public ContentType $content_type = ContentType::PODCAST,
public Collection $guests = new ArrayCollection()
) {
Mapper::hydrate($this->_entity, $this, ['content_type']);
Mapper::hydrate($this->_entity, $this);
}
}
39 changes: 39 additions & 0 deletions src/Domain/Content/Entity/Podcast/Episode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Domain\Content\Entity\Podcast;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Domain\Authentication\Entity\User;
use Domain\Content\Entity\Content;
use Domain\Content\Enum\ContentType;
use Domain\Content\Enum\EpisodeType;
Expand All @@ -28,11 +31,17 @@ class Episode extends Content

private ?File $audio_file = null;

/**
* @var Collection<User>
*/
private Collection $guests;

public function __construct()
{
parent::__construct();
$this->audio = EmbeddedFile::default();
$this->content_type = ContentType::PODCAST;
$this->guests = new ArrayCollection();
}

public function getContentType(): ContentType
Expand Down Expand Up @@ -105,4 +114,34 @@ public function setEpisodeNumber(?int $episode_number): self

return $this;
}

public function getGuests(): Collection
{
return $this->guests;
}

public function setGuests(Collection $guests): self
{
$this->guests = $guests;

return $this;
}

public function addGuest(User $guest): self
{
if (! $this->guests->contains($guest)) {
$this->guests->add($guest);
}

return $this;
}

public function removeGuest(User $guest): self
{
if ($this->guests->contains($guest)) {
$this->guests->removeElement($guest);
}

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Infrastructure\Authentication\Symfony\Form\Field;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Domain\Authentication\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
use Symfony\UX\Autocomplete\Form\ParentEntityAutocompleteType;

/**
* Class UserAutocompleteField.
*
* @author bernard-ng <[email protected]>
*/
#[AsEntityAutocompleteField]
class UserAutocompleteField extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'class' => User::class,
'autocomplete' => true,
'choice_label' => 'username',
'placeholder' => 'pseudo de l\'utilisateur',
'filter_query' => function (QueryBuilder $qb, string $query, EntityRepository $repository) {
if (! $query) {
return;
}

$qb->andWhere('entity.name LIKE :filter OR entity.username.username LIKE :filter')
->setParameter('filter', '%' . $query . '%');
},
]);
}

public function getParent(): string
{
return ParentEntityAutocompleteType::class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,15 @@
<many-to-one field="season" target-entity="Domain\Content\Entity\Podcast\Season" inversed-by="episodes">
<join-column nullable="true" on-delete="SET NULL" />
</many-to-one>
<many-to-many field="guests" target-entity="Domain\Authentication\Entity\User">
<join-table name="content_podcast_episode_guests">
<join-columns>
<join-column name="episode_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</join-columns>
<inverse-join-columns>
<join-column name="guest_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Application\Content\Command\Podcast\CreateEpisodeCommand;
use Domain\Content\Entity\Podcast\Season;
use Infrastructure\Authentication\Symfony\Form\Field\UserAutocompleteField;
use Infrastructure\Content\Symfony\Form\Type\AbstractContentType;
use Infrastructure\Content\Symfony\Form\Type\EpisodeTypeType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
Expand Down Expand Up @@ -42,6 +43,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('episode_number', IntegerType::class, [
'label' => 'content.forms.labels.episode_number',
])
->add('guests', UserAutocompleteField::class, [
'label' => 'content.forms.labels.guests',
'multiple' => true,
'required' => false,
])
;
$this->addContentOptions($builder);
}
Expand Down
24 changes: 24 additions & 0 deletions src/Infrastructure/Shared/Twig/Podcast/AppPodcastGuestCard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Infrastructure\Shared\Twig\Podcast;

use Domain\Authentication\Entity\User;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;

/**
* Class AppPodcastGuestCard.
*
* @author bernard-ng <[email protected]>
*/
#[AsTwigComponent(template: '@app/shared/component/podcast/guest_card.html.twig')]
final class AppPodcastGuestCard
{
public User $guest;

public function preMount(User $guest): void
{
$this->guest = $guest;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% if app.user.avatar.name %}
<img src="{{ vich_uploader_asset(app.user, 'avatar_file') }}" alt="{{ app.user.userIdentifier }}">
{% else %}
<twig:Icon name="user"/>
<twig:DashliteIcon name="user"/>
{% endif %}
</div>
<div class="user-info">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
</li>
<li>
<a href="{{ path('auth_setting_backup_codes_export') }}" class="btn btn-primary">
<twig:Icon name="download"/>
<twig:DashliteIcon name="download"/>
<span>Télécharger (csv)</span>
</a>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</div>
</div>
<button class="btn btn-primary mt-4">
<twig:Icon name="save-fill"/>
<twig:DashliteIcon name="save-fill"/>
<span>{{ 'global.submit' | trans([], 'messages') }}</span>
</button>
</div>
Expand Down
56 changes: 28 additions & 28 deletions templates/admin/domain/authentication/user/show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@
<ul class="nav nav-tabs nav-tabs-mb-icon nav-tabs-card">
<li class="nav-item">
<a class="nav-link active" href="#">
<twig:Icon name="user-circle" />
<twig:DashliteIcon name="user-circle" />
<span>Personal</span>
</a>
</li>
<li class="nav-item"><a class="nav-link" href="#">
<twig:Icon name="repeat" />
<twig:DashliteIcon name="repeat" />
<span>Contenus</span>
</a>
</li>
<li class="nav-item"><a class="nav-link" href="#">
<twig:Icon name="repeat" />
<twig:DashliteIcon name="repeat" />
<span>Transactions</span>
</a>
</li>
<li class="nav-item nav-item-trigger d-xxl-none">
<a href="#" class="toggle btn btn-icon btn-trigger" data-target="userAside">
<twig:Icon name="user-list-fill" />
<twig:DashliteIcon name="user-list-fill" />
</a>
</li>
</ul>
Expand All @@ -47,30 +47,30 @@
<twig:block name="content">
<div class="nk-block">
<twig:DashliteDataList title="Informations personnelles" :description="data.biography">
<twig:DataItem label="Nom complet" :value="data.name" />
<twig:DataItem label="Nom d'utilisateur" :value="data.username" />
<twig:DataItem label="Email" :value="data.email" />
<twig:DataItem label="Pronoms" :value="data.pronouns" />
<twig:DataItem label="Poste" :value="data.jobTitle" />
<twig:DataItem label="Genre" :value="data.gender.translationKey | trans([], 'authentication')" />
<twig:DataItem label="Pays" :value="data.country | flag" />
<twig:DataItem label="Rôle" :value="data.roles | last | badge " />
<twig:DataItem label="Linkedin" :value="data.linkedinUrl" link="true" />
<twig:DataItem label="Twitter" :value="data.twitterUrl" link="true" />
<twig:DataItem label="Github" :value="data.githubUrl" link="true" />
<twig:DataItem label="Site Internet" :value="data.githubUrl" link="true"/>
<twig:DataItem label="Flux Rss" :value="data.rssUrl" link="true" />
<twig:DashliteDataItem label="Nom complet" :value="data.name" />
<twig:DashliteDataItem label="Nom d'utilisateur" :value="data.username" />
<twig:DashliteDataItem label="Email" :value="data.email" />
<twig:DashliteDataItem label="Pronoms" :value="data.pronouns" />
<twig:DashliteDataItem label="Poste" :value="data.jobTitle" />
<twig:DashliteDataItem label="Genre" :value="data.gender.translationKey | trans([], 'authentication')" />
<twig:DashliteDataItem label="Pays" :value="data.country | flag" />
<twig:DashliteDataItem label="Rôle" :value="data.roles | last | badge " />
<twig:DashliteDataItem label="Linkedin" :value="data.linkedinUrl" link="true" />
<twig:DashliteDataItem label="Twitter" :value="data.twitterUrl" link="true" />
<twig:DashliteDataItem label="Github" :value="data.githubUrl" link="true" />
<twig:DashliteDataItem label="Site Internet" :value="data.githubUrl" link="true"/>
<twig:DashliteDataItem label="Flux Rss" :value="data.rssUrl" link="true" />
</twig:DashliteDataList>
<div class="nk-divider divider md"></div>
<twig:DashliteDataList title="Informations supplémentaires">
<twig:DataItem label="Bannis" :value="data.banned | boolean" />
<twig:DataItem label="Email vérifié" :value="data.isEmailVerified | boolean" />
<twig:DataItem label="Thème sombre" :value="data.isDarkTheme | boolean" />
<twig:DataItem label="Téléphone vérifié" :value="data.isPhoneNumberVerified | boolean" />
<twig:DataItem label="Newsletter" :value="data.isSubscribedNewsletter | boolean" />
<twig:DataItem label="Marketing" :value="data.isSubscribedMarketing | boolean" />
<twig:DataItem label="2FA activé" :value="data.twoFactorEnabled | boolean" />
<twig:DataItem label="Date de bannissement" :value="data.bannedAt ? data.bannedAt | date : '-'" />
<twig:DashliteDataItem label="Bannis" :value="data.banned | boolean" />
<twig:DashliteDataItem label="Email vérifié" :value="data.isEmailVerified | boolean" />
<twig:DashliteDataItem label="Thème sombre" :value="data.isDarkTheme | boolean" />
<twig:DashliteDataItem label="Téléphone vérifié" :value="data.isPhoneNumberVerified | boolean" />
<twig:DashliteDataItem label="Newsletter" :value="data.isSubscribedNewsletter | boolean" />
<twig:DashliteDataItem label="Marketing" :value="data.isSubscribedMarketing | boolean" />
<twig:DashliteDataItem label="2FA activé" :value="data.twoFactorEnabled | boolean" />
<twig:DashliteDataItem label="Date de bannissement" :value="data.bannedAt ? data.bannedAt | date : '-'" />
</twig:DashliteDataList>
</div>
</twig:block>
Expand Down Expand Up @@ -105,7 +105,7 @@
redirect="{{ path('admin_auth_user_show', {id: data.id}) }}"
title="{{ 'global.ban' | trans([], 'messages') }}"
>
<twig:Icon name="shield" />
<twig:DashliteIcon name="shield" />
</button>
{% else %}
<button
Expand All @@ -115,11 +115,11 @@
redirect="{{ path('admin_auth_user_show', {id: data.id}) }}"
title="{{ 'global.unban' | trans([], 'messages') }}"
>
<twig:Icon name="shield-off" />
<twig:DashliteIcon name="shield-off" />
</button>
{% endif %}
</li>
<li><a href="{{ path('admin_auth_user_email', {id: data.id}) }}" class="btn text-soft btn-trigger btn-icon"><twig:Icon name="mail"/></a></li>
<li><a href="{{ path('admin_auth_user_email', {id: data.id}) }}" class="btn text-soft btn-trigger btn-icon"><twig:DashliteIcon name="mail"/></a></li>
</ul>
</div>
<div class="card-inner"><h6 class="overline-title-alt mb-2">Additional</h6>
Expand Down
Loading

0 comments on commit e67472b

Please sign in to comment.