Implement basic wishlist

This commit is contained in:
Jannis Portmann 2021-05-04 11:52:20 +02:00
parent d80d667e0d
commit f2dd4da50b
9 changed files with 315 additions and 0 deletions

View file

@ -0,0 +1,36 @@
<?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 Version20210503161858 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 wish_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE wish (id INT NOT NULL, by_user_id INT DEFAULT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_D7D174C9DC9C2434 ON wish (by_user_id)');
$this->addSql('ALTER TABLE wish ADD CONSTRAINT FK_D7D174C9DC9C2434 FOREIGN KEY (by_user_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('CREATE SCHEMA public');
$this->addSql('DROP SEQUENCE wish_id_seq CASCADE');
$this->addSql('DROP TABLE wish');
}
}

View file

@ -4,6 +4,7 @@ namespace App\Controller\Admin;
use App\Entity\User;
use App\Entity\Offering;
use App\Entity\Wish;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
@ -32,5 +33,6 @@ class DashboardController extends AbstractDashboardController
yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home');
yield MenuItem::linkToCrud('User', 'fas fa-user', User::class);
yield MenuItem::linkToCrud('Offering', 'fas fa-seedling', Offering::class);
yield MenuItem::linkToCrud('Wish', 'fas fa-star', Wish::class);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace App\Controller\Admin;
use App\Entity\Wish;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
class WishCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Wish::class;
}
public function configureFields(string $pageName): iterable
{
return [
yield AssociationField::new('byUser'),
yield TextField::new('title'),
];
}
}

View file

@ -2,12 +2,27 @@
namespace App\Controller;
use App\Entity\Wish;
use App\Form\WishFormType;
use App\Repository\WishRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Twig\Environment;
class UserController extends AbstractController
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
#[Route('/user', name: 'user_page')]
public function user(): Response
{
@ -15,4 +30,30 @@ class UserController extends AbstractController
'user' => $this->getUser(),
]);
}
#[Route('/wishlist', name: 'wishlist')]
public function wishlist(Request $request, WishRepository $wishRepository): Response
{
$wish = new Wish();
$form = $this->createForm(WishFormType::class, $wish);
$user = $this->getUser();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$wish->setByUser($user);
$this->entityManager->persist($wish);
$this->entityManager->flush();
$this->addFlash("success", "Successfully added the new offering!");
return $this->redirectToRoute('wishlist');
}
return $this->render('user/wish.html.twig', [
'user' => $this->getUser(),
'wishes' => $wishRepository->findByUser($user),
'wish_form' => $form->createView(),
]);
}
}

View file

@ -54,9 +54,15 @@ class User implements UserInterface
*/
private $offerings;
/**
* @ORM\OneToMany(targetEntity=Wish::class, mappedBy="byUser")
*/
private $wishes;
public function __construct()
{
$this->offerings = new ArrayCollection();
$this->wishes = new ArrayCollection();
}
public function getId(): ?int
@ -193,4 +199,34 @@ class User implements UserInterface
{
return (string) $this->getUsername();
}
/**
* @return Collection|Wish[]
*/
public function getWishes(): Collection
{
return $this->wishes;
}
public function addWish(Wish $wish): self
{
if (!$this->wishes->contains($wish)) {
$this->wishes[] = $wish;
$wish->setByUser($this);
}
return $this;
}
public function removeWish(Wish $wish): self
{
if ($this->wishes->removeElement($wish)) {
// set the owning side to null (unless already changed)
if ($wish->getByUser() === $this) {
$wish->setByUser(null);
}
}
return $this;
}
}

63
src/Entity/Wish.php Normal file
View file

@ -0,0 +1,63 @@
<?php
namespace App\Entity;
use App\Repository\WishRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=WishRepository::class)
*/
class Wish
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="wishes")
*/
private $byUser;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getByUser(): ?User
{
return $this->byUser;
}
public function setByUser(?User $byUser): self
{
$this->byUser = $byUser;
return $this;
}
public function __toString(): string
{
return (string) $this->getTitle();
}
}

27
src/Form/WishFormType.php Normal file
View file

@ -0,0 +1,27 @@
<?php
namespace App\Form;
use App\Entity\Wish;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class WishFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Wish::class,
]);
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace App\Repository;
use App\Entity\Wish;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method Wish|null find($id, $lockMode = null, $lockVersion = null)
* @method Wish|null findOneBy(array $criteria, array $orderBy = null)
* @method Wish[] findAll()
* @method Wish[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class WishRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Wish::class);
}
// /**
// * @return Wish[] Returns an array of Wish objects
// */
public function findByUser($value)
{
return $this->createQueryBuilder('w')
->andWhere('w.byUser = :val')
->setParameter('val', $value)
->orderBy('w.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
/*
public function findOneBySomeField($value): ?Wish
{
return $this->createQueryBuilder('w')
->andWhere('w.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

View file

@ -0,0 +1,36 @@
{% extends 'base.html.twig' %}
{% block title %}Whishlist{% endblock %}
{% block body %}
{% for message in app.flashes('success') %}
<div class="alert alert-success" role="alert">
{{ message }}
</div>
{% endfor %}
<div class="mb-3">
<h1>Your Whishlist</h1>
</div>
<div class="mb-3">
{% if wishes == [] %}
<div class="alert alert-warning" role="alert">
There are currently no wishes!
</div>
{% else %}
<ul class="list-group">
{% for wish in wishes %}
<li class="list-group-item"> {{ wish.title }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
<hr>
<div mb-3>
<h3><i class="fas fa-star"></i> New wish</h3>
{{ form(wish_form) }}
</div>
{% endblock %}