فهرست منبع

Ajout de film dans commonList

Francois DROUHARD 901 2 ماه پیش
والد
کامیت
1c0c5e05bd

+ 8 - 22
assets/controllers/sortable_controller.js

@@ -1,36 +1,22 @@
 import { Controller } from "@hotwired/stimulus";
 
 import Sortable from 'sortablejs'
-
 export default class extends Controller {
     connect() {
-        this.sortable = new Sortable(this.element, {
-            animation: 150,
-            handle: 'tr',
-            onEnd: this.end.bind(this),
+        this.sortable = Sortable.create(this.element, {
+            onEnd: this.end.bind(this)
         });
     }
 
     end(event) {
-        let order = [];
-        this.element.querySelectorAll('tr').forEach((row, index) => {
-            order.push({
-                id: row.dataset.id,
-                position: index + 1
-            });
-        });
+        // Envoyer les nouvelles positions au serveur
+        const data = new FormData();
+        data.append('oldIndex', event.oldIndex);
+        data.append('newIndex', event.newIndex);
 
-        fetch(this.data.get('url'), {
+        fetch('/update-order', {
             method: 'POST',
-            headers: {
-                'Content-Type': 'application/json',
-                'X-Requested-With': 'XMLHttpRequest'
-            },
-            body: JSON.stringify({order: order})
-        }).then(Response => {
-            if(Response.ok) {
-                this.sortable.sort(order.map(item =>item.id))
-            }
+            body: data
         });
     }
 }

+ 40 - 0
migrations/Version20250113095919.php

@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DoctrineMigrations;
+
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\Migrations\AbstractMigration;
+
+/**
+ * Auto-generated Migration: Please modify to your needs!
+ */
+final class Version20250113095919 extends AbstractMigration
+{
+    public function getDescription(): string
+    {
+        return '';
+    }
+
+    public function up(Schema $schema): void
+    {
+        // this up() migration is auto-generated, please modify it to your needs
+        $this->addSql('CREATE SEQUENCE common_list_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+        $this->addSql('CREATE TABLE common_list (id INT NOT NULL, film_id INT NOT NULL, added_by_id INT NOT NULL, date_added DATE NOT NULL, PRIMARY KEY(id))');
+        $this->addSql('CREATE INDEX IDX_F450E089567F5183 ON common_list (film_id)');
+        $this->addSql('CREATE INDEX IDX_F450E08955B127A4 ON common_list (added_by_id)');
+        $this->addSql('COMMENT ON COLUMN common_list.date_added IS \'(DC2Type:date_immutable)\'');
+        $this->addSql('ALTER TABLE common_list ADD CONSTRAINT FK_F450E089567F5183 FOREIGN KEY (film_id) REFERENCES film (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+        $this->addSql('ALTER TABLE common_list ADD CONSTRAINT FK_F450E08955B127A4 FOREIGN KEY (added_by_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+    }
+
+    public function down(Schema $schema): void
+    {
+        // this down() migration is auto-generated, please modify it to your needs
+        $this->addSql('DROP SEQUENCE common_list_id_seq CASCADE');
+        $this->addSql('ALTER TABLE common_list DROP CONSTRAINT FK_F450E089567F5183');
+        $this->addSql('ALTER TABLE common_list DROP CONSTRAINT FK_F450E08955B127A4');
+        $this->addSql('DROP TABLE common_list');
+    }
+}

+ 44 - 0
migrations/Version20250113100815.php

@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DoctrineMigrations;
+
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\Migrations\AbstractMigration;
+
+/**
+ * Auto-generated Migration: Please modify to your needs!
+ */
+final class Version20250113100815 extends AbstractMigration
+{
+    public function getDescription(): string
+    {
+        return '';
+    }
+
+    public function up(Schema $schema): void
+    {
+        // this up() migration is auto-generated, please modify it to your needs
+        $this->addSql('CREATE SEQUENCE user_list_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+        $this->addSql('CREATE TABLE user_list (id INT NOT NULL, viewer_id INT NOT NULL, position INT DEFAULT NULL, PRIMARY KEY(id))');
+        $this->addSql('CREATE INDEX IDX_3E49B4D16C59C752 ON user_list (viewer_id)');
+        $this->addSql('CREATE TABLE user_list_film (user_list_id INT NOT NULL, film_id INT NOT NULL, PRIMARY KEY(user_list_id, film_id))');
+        $this->addSql('CREATE INDEX IDX_C76AEC2F65A30881 ON user_list_film (user_list_id)');
+        $this->addSql('CREATE INDEX IDX_C76AEC2F567F5183 ON user_list_film (film_id)');
+        $this->addSql('ALTER TABLE user_list ADD CONSTRAINT FK_3E49B4D16C59C752 FOREIGN KEY (viewer_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+        $this->addSql('ALTER TABLE user_list_film ADD CONSTRAINT FK_C76AEC2F65A30881 FOREIGN KEY (user_list_id) REFERENCES user_list (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+        $this->addSql('ALTER TABLE user_list_film ADD CONSTRAINT FK_C76AEC2F567F5183 FOREIGN KEY (film_id) REFERENCES film (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+    }
+
+    public function down(Schema $schema): void
+    {
+        // this down() migration is auto-generated, please modify it to your needs
+        $this->addSql('DROP SEQUENCE user_list_id_seq CASCADE');
+        $this->addSql('ALTER TABLE user_list DROP CONSTRAINT FK_3E49B4D16C59C752');
+        $this->addSql('ALTER TABLE user_list_film DROP CONSTRAINT FK_C76AEC2F65A30881');
+        $this->addSql('ALTER TABLE user_list_film DROP CONSTRAINT FK_C76AEC2F567F5183');
+        $this->addSql('DROP TABLE user_list');
+        $this->addSql('DROP TABLE user_list_film');
+    }
+}

+ 14 - 5
src/Controller/IndexController.php

@@ -2,8 +2,10 @@
 
 namespace App\Controller;
 
+use App\Entity\CommonList;
 use App\Entity\Film;
 use App\Form\FilmType;
+use App\Repository\CommonListRepository;
 use App\Repository\FilmRepository;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -14,22 +16,28 @@ use Symfony\Component\Routing\Attribute\Route;
 class IndexController extends AbstractController
 {
     #[Route('/{id?}', name: 'app_index', methods: ['GET', 'POST'], requirements: ['id' => '\d+'])]
-    public function index(Request $request, FilmRepository $filmRepository, ?Film $film = null): Response
+    public function index(Request $request, FilmRepository $filmRepository, CommonListRepository $commonListRepository, ?Film $film = null): Response
     {
         $film = $film ?? new Film();
         $form = $this->createForm(FilmType::class, $film);
-        $films = $filmRepository->findAll();
+
+        $commonList = $commonListRepository->findAll();
 
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
+            if (null === $film->getId()) {
+                $commonList = CommonList::new($film, $this->getUser());
+            }
+
             $filmRepository->save($film, true);
+            $commonListRepository->save($commonList, true);
 
             return $this->redirectToRoute('app_index', [], RedirectResponse::HTTP_SEE_OTHER);
         }
 
         return $this->render('index/index.html.twig', [
-            'films' => $films,
+            'commonList' => $commonList,
             'form' => $form
         ]);
     }
@@ -37,8 +45,9 @@ class IndexController extends AbstractController
     #[Route('/update-order', name: 'update_order', methods: ['POST'])]
     public function updateOrder(Request $request): Response
     {
-        $order = json_decode($request->getContent(), true)['order'];
-        dump($order);
+        dump($request->get('oldIndex'));
+        dump($request->get('newIndex'));
+
 
         return new Response('Order updated', Response::HTTP_OK);
     }

+ 79 - 0
src/Entity/CommonList.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\CommonListRepository;
+use Doctrine\DBAL\Types\Types;
+use Doctrine\ORM\Mapping as ORM;
+
+#[ORM\Entity(repositoryClass: CommonListRepository::class)]
+class CommonList
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'commonLists')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Film $film = null;
+
+    #[ORM\ManyToOne(inversedBy: 'commonLists')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?User $addedBy = null;
+
+    #[ORM\Column(type: Types::DATE_IMMUTABLE)]
+    private ?\DateTimeImmutable $dateAdded = null;
+
+    static public function new(Film $film, User $user): static
+    {
+        $common = new Static();
+        $common
+            ->setFilm($film)
+            ->setAddedBy($user)
+            ->setDateAdded(new \DateTimeImmutable('now'))
+        ;
+        return $common;
+    }
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getFilm(): ?Film
+    {
+        return $this->film;
+    }
+
+    public function setFilm(?Film $film): static
+    {
+        $this->film = $film;
+
+        return $this;
+    }
+
+    public function getAddedBy(): ?User
+    {
+        return $this->addedBy;
+    }
+
+    public function setAddedBy(?User $addedBy): static
+    {
+        $this->addedBy = $addedBy;
+
+        return $this;
+    }
+
+    public function getDateAdded(): ?\DateTimeImmutable
+    {
+        return $this->dateAdded;
+    }
+
+    public function setDateAdded(\DateTimeImmutable $dateAdded): static
+    {
+        $this->dateAdded = $dateAdded;
+
+        return $this;
+    }
+}

+ 77 - 0
src/Entity/Film.php

@@ -3,6 +3,8 @@
 namespace App\Entity;
 
 use App\Repository\FilmRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: FilmRepository::class)]
@@ -22,6 +24,24 @@ class Film
     #[ORM\Column(length: 255, nullable: true)]
     private ?string $genre = null;
 
+    /**
+     * @var Collection<int, CommonList>
+     */
+    #[ORM\OneToMany(targetEntity: CommonList::class, mappedBy: 'film', orphanRemoval: true)]
+    private Collection $commonLists;
+
+    /**
+     * @var Collection<int, UserList>
+     */
+    #[ORM\ManyToMany(targetEntity: UserList::class, mappedBy: 'films')]
+    private Collection $userLists;
+
+    public function __construct()
+    {
+        $this->commonLists = new ArrayCollection();
+        $this->userLists = new ArrayCollection();
+    }
+
     public function getId(): ?int
     {
         return $this->id;
@@ -62,4 +82,61 @@ class Film
 
         return $this;
     }
+
+    /**
+     * @return Collection<int, CommonList>
+     */
+    public function getCommonLists(): Collection
+    {
+        return $this->commonLists;
+    }
+
+    public function addCommonList(CommonList $commonList): static
+    {
+        if (!$this->commonLists->contains($commonList)) {
+            $this->commonLists->add($commonList);
+            $commonList->setFilm($this);
+        }
+
+        return $this;
+    }
+
+    public function removeCommonList(CommonList $commonList): static
+    {
+        if ($this->commonLists->removeElement($commonList)) {
+            // set the owning side to null (unless already changed)
+            if ($commonList->getFilm() === $this) {
+                $commonList->setFilm(null);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return Collection<int, UserList>
+     */
+    public function getUserLists(): Collection
+    {
+        return $this->userLists;
+    }
+
+    public function addUserList(UserList $userList): static
+    {
+        if (!$this->userLists->contains($userList)) {
+            $this->userLists->add($userList);
+            $userList->addFilm($this);
+        }
+
+        return $this;
+    }
+
+    public function removeUserList(UserList $userList): static
+    {
+        if ($this->userLists->removeElement($userList)) {
+            $userList->removeFilm($this);
+        }
+
+        return $this;
+    }
 }

+ 80 - 0
src/Entity/User.php

@@ -3,6 +3,8 @@
 namespace App\Entity;
 
 use App\Repository\UserRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
 use Symfony\Component\Security\Core\User\UserInterface;
@@ -36,6 +38,24 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\Column]
     private ?string $password = null;
 
+    /**
+     * @var Collection<int, CommonList>
+     */
+    #[ORM\OneToMany(targetEntity: CommonList::class, mappedBy: 'addedBy')]
+    private Collection $commonLists;
+
+    /**
+     * @var Collection<int, UserList>
+     */
+    #[ORM\OneToMany(targetEntity: UserList::class, mappedBy: 'viewer', orphanRemoval: true)]
+    private Collection $userLists;
+
+    public function __construct()
+    {
+        $this->commonLists = new ArrayCollection();
+        $this->userLists = new ArrayCollection();
+    }
+
     public function getId(): ?int
     {
         return $this->id;
@@ -110,4 +130,64 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
         // If you store any temporary, sensitive data on the user, clear it here
         // $this->plainPassword = null;
     }
+
+    /**
+     * @return Collection<int, CommonList>
+     */
+    public function getCommonLists(): Collection
+    {
+        return $this->commonLists;
+    }
+
+    public function addCommonList(CommonList $commonList): static
+    {
+        if (!$this->commonLists->contains($commonList)) {
+            $this->commonLists->add($commonList);
+            $commonList->setAddedBy($this);
+        }
+
+        return $this;
+    }
+
+    public function removeCommonList(CommonList $commonList): static
+    {
+        if ($this->commonLists->removeElement($commonList)) {
+            // set the owning side to null (unless already changed)
+            if ($commonList->getAddedBy() === $this) {
+                $commonList->setAddedBy(null);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return Collection<int, UserList>
+     */
+    public function getUserLists(): Collection
+    {
+        return $this->userLists;
+    }
+
+    public function addUserList(UserList $userList): static
+    {
+        if (!$this->userLists->contains($userList)) {
+            $this->userLists->add($userList);
+            $userList->setViewer($this);
+        }
+
+        return $this;
+    }
+
+    public function removeUserList(UserList $userList): static
+    {
+        if ($this->userLists->removeElement($userList)) {
+            // set the owning side to null (unless already changed)
+            if ($userList->getViewer() === $this) {
+                $userList->setViewer(null);
+            }
+        }
+
+        return $this;
+    }
 }

+ 88 - 0
src/Entity/UserList.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\UserListRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
+
+#[ORM\Entity(repositoryClass: UserListRepository::class)]
+class UserList
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'userLists')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?User $viewer = null;
+
+    /**
+     * @var Collection<int, Film>
+     */
+    #[ORM\ManyToMany(targetEntity: Film::class, inversedBy: 'userLists')]
+    private Collection $films;
+
+    #[ORM\Column(nullable: true)]
+    private ?int $position = null;
+
+    public function __construct()
+    {
+        $this->films = new ArrayCollection();
+    }
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getViewer(): ?User
+    {
+        return $this->viewer;
+    }
+
+    public function setViewer(?User $viewer): static
+    {
+        $this->viewer = $viewer;
+
+        return $this;
+    }
+
+    /**
+     * @return Collection<int, Film>
+     */
+    public function getFilms(): Collection
+    {
+        return $this->films;
+    }
+
+    public function addFilm(Film $film): static
+    {
+        if (!$this->films->contains($film)) {
+            $this->films->add($film);
+        }
+
+        return $this;
+    }
+
+    public function removeFilm(Film $film): static
+    {
+        $this->films->removeElement($film);
+
+        return $this;
+    }
+
+    public function getPosition(): ?int
+    {
+        return $this->position;
+    }
+
+    public function setPosition(?int $position): static
+    {
+        $this->position = $position;
+
+        return $this;
+    }
+}

+ 59 - 0
src/Repository/CommonListRepository.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\CommonList;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends ServiceEntityRepository<CommonList>
+ */
+class CommonListRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, CommonList::class);
+    }
+
+    public function save(CommonList $commonList, bool $flush = false): void
+    {
+        $this->getEntityManager()->persist($commonList);
+        if ($flush) {
+            $this->getEntityManager()->flush();
+        }
+    }
+
+    public function remove(CommonList $commonList, bool $flush = false): void
+    {
+        $this->getEntityManager()->remove($commonList);
+        if ($flush) {
+            $this->getEntityManager()->flush();
+        }
+    }
+
+    //    /**
+    //     * @return CommonList[] Returns an array of CommonList objects
+    //     */
+    //    public function findByExampleField($value): array
+    //    {
+    //        return $this->createQueryBuilder('c')
+    //            ->andWhere('c.exampleField = :val')
+    //            ->setParameter('val', $value)
+    //            ->orderBy('c.id', 'ASC')
+    //            ->setMaxResults(10)
+    //            ->getQuery()
+    //            ->getResult()
+    //        ;
+    //    }
+
+    //    public function findOneBySomeField($value): ?CommonList
+    //    {
+    //        return $this->createQueryBuilder('c')
+    //            ->andWhere('c.exampleField = :val')
+    //            ->setParameter('val', $value)
+    //            ->getQuery()
+    //            ->getOneOrNullResult()
+    //        ;
+    //    }
+}

+ 43 - 0
src/Repository/UserListRepository.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\UserList;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends ServiceEntityRepository<UserList>
+ */
+class UserListRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, UserList::class);
+    }
+
+    //    /**
+    //     * @return UserList[] Returns an array of UserList objects
+    //     */
+    //    public function findByExampleField($value): array
+    //    {
+    //        return $this->createQueryBuilder('u')
+    //            ->andWhere('u.exampleField = :val')
+    //            ->setParameter('val', $value)
+    //            ->orderBy('u.id', 'ASC')
+    //            ->setMaxResults(10)
+    //            ->getQuery()
+    //            ->getResult()
+    //        ;
+    //    }
+
+    //    public function findOneBySomeField($value): ?UserList
+    //    {
+    //        return $this->createQueryBuilder('u')
+    //            ->andWhere('u.exampleField = :val')
+    //            ->setParameter('val', $value)
+    //            ->getQuery()
+    //            ->getOneOrNullResult()
+    //        ;
+    //    }
+}

+ 6 - 1
templates/index/index.html.twig

@@ -13,10 +13,13 @@
             <th>Nom</th>
             <th>Realisateur</th>
             <th>Genre</th>
+            <th>Ajouté par</th>
+            <th>Date d'ajout</th>
         </tr>
     </thead>
     <tbody data-controller="sortable" data-sortable-url="{{ path('update_order') }}">
-        {% for film in films %}
+        {% for entry in commonList %}
+        {% set film = entry.film %}
         <tr data-id="{{ film.id }}">
             <td>
                 <a href="{{ path('app_index', {'id': film.id} ) }}"><i class="fa fa-edit"></i></a>
@@ -24,6 +27,8 @@
             <td>{{ film.name }}</td>
             <td>{{ film.realisateur }}</td>
             <td>{{ film.genre }}</td>
+            <td>{{ entry.addedBy.email }}</td>
+            <td>{{ entry.dateAdded | date('d/m/Y') }}
         </tr>
         {% endfor %}
     </tbody>