Implement basic wishlist
This commit is contained in:
parent
d80d667e0d
commit
f2dd4da50b
9 changed files with 315 additions and 0 deletions
36
migrations/Version20210503161858.php
Normal file
36
migrations/Version20210503161858.php
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ namespace App\Controller\Admin;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Entity\Offering;
|
use App\Entity\Offering;
|
||||||
|
use App\Entity\Wish;
|
||||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
|
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
|
||||||
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
|
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
|
||||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
|
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
|
||||||
|
@ -32,5 +33,6 @@ class DashboardController extends AbstractDashboardController
|
||||||
yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home');
|
yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home');
|
||||||
yield MenuItem::linkToCrud('User', 'fas fa-user', User::class);
|
yield MenuItem::linkToCrud('User', 'fas fa-user', User::class);
|
||||||
yield MenuItem::linkToCrud('Offering', 'fas fa-seedling', Offering::class);
|
yield MenuItem::linkToCrud('Offering', 'fas fa-seedling', Offering::class);
|
||||||
|
yield MenuItem::linkToCrud('Wish', 'fas fa-star', Wish::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
src/Controller/Admin/WishCrudController.php
Normal file
24
src/Controller/Admin/WishCrudController.php
Normal 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'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,27 @@
|
||||||
|
|
||||||
namespace App\Controller;
|
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\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Twig\Environment;
|
||||||
|
|
||||||
class UserController extends AbstractController
|
class UserController extends AbstractController
|
||||||
{
|
{
|
||||||
|
private $entityManager;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
|
{
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/user', name: 'user_page')]
|
#[Route('/user', name: 'user_page')]
|
||||||
public function user(): Response
|
public function user(): Response
|
||||||
{
|
{
|
||||||
|
@ -15,4 +30,30 @@ class UserController extends AbstractController
|
||||||
'user' => $this->getUser(),
|
'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(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,15 @@ class User implements UserInterface
|
||||||
*/
|
*/
|
||||||
private $offerings;
|
private $offerings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity=Wish::class, mappedBy="byUser")
|
||||||
|
*/
|
||||||
|
private $wishes;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->offerings = new ArrayCollection();
|
$this->offerings = new ArrayCollection();
|
||||||
|
$this->wishes = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
@ -193,4 +199,34 @@ class User implements UserInterface
|
||||||
{
|
{
|
||||||
return (string) $this->getUsername();
|
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
63
src/Entity/Wish.php
Normal 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
27
src/Form/WishFormType.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
50
src/Repository/WishRepository.php
Normal file
50
src/Repository/WishRepository.php
Normal 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()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
36
templates/user/wish.html.twig
Normal file
36
templates/user/wish.html.twig
Normal 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 %}
|
Reference in a new issue