Feat: Add contacts
This commit is contained in:
1 parent
f5fee787a0
commit
3fd4c6ca54
19 files changed
+658
-2
No files matched your search
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin\System\Contact;
|
||||
|
||||
use App\Entity\Contact;
|
||||
use App\Entity\Upload;
|
||||
use App\Entity\User;
|
||||
use App\Form\ContactType;
|
||||
use App\Model\AjaxModalResponseDto;
|
||||
use App\Service\Upload\UploadHandler;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
class CreateController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UploadHandler $uploadHandler,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/admin/system/contact/create', name: 'app_admin_system_contact_create')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$response = new AjaxModalResponseDto();
|
||||
$contact = new Contact();
|
||||
$formAction = $this->generateUrl('app_admin_system_contact_create');
|
||||
|
||||
// Handle upload independently from form submission to avoid issues with failing validation
|
||||
$uploadSession = $this->uploadHandler->getUploadSession();
|
||||
if (true === $request->isMethod('POST') && 0 < $uploadSession->getCount()) {
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
|
||||
$photo = Upload::fromUploadDto($uploadSession->getUploads()->first(), $user, Upload::TYPE_PHOTO);
|
||||
$contact->setPhoto($photo);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->uploadHandler->moveUploadSessionFilesFromOrphanage(Upload::TYPE_PHOTO, $uploadSession);
|
||||
$this->uploadHandler->destroyUploadSession();
|
||||
}
|
||||
|
||||
$form = $this->createForm(
|
||||
ContactType::class,
|
||||
$contact,
|
||||
[
|
||||
'action' => $formAction,
|
||||
'ajax_submit' => true,
|
||||
'upload_session' => $uploadSession,
|
||||
]
|
||||
);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->entityManager->persist($contact);
|
||||
$this->entityManager->flush();
|
||||
$this->addFlash('success', 'Der Ansprechpartner wurde hinzugefügt');
|
||||
$this->logger->info('Create contact', [
|
||||
'contact' => $contact->getName(),
|
||||
]);
|
||||
|
||||
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_contact_index'));
|
||||
} else {
|
||||
$response->setContent($this->renderView('admin/system/contact/create.html.twig', [
|
||||
'form' => $form,
|
||||
]));
|
||||
}
|
||||
|
||||
return $this->json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin\System\Contact;
|
||||
|
||||
use App\Entity\Contact;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
class DeleteController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/admin/system/contact/delete/{id}', name: 'app_admin_system_contact_delete')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(Contact $contact): Response
|
||||
{
|
||||
$this->entityManager->remove($contact);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'Der Ansprechpartner wurde gelöscht');
|
||||
$this->logger->info('Delete contact', [
|
||||
'contact' => $contact->getName(),
|
||||
]);
|
||||
|
||||
return $this->redirectToRoute('app_admin_system_contact_index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin\System\Contact;
|
||||
|
||||
use App\Entity\Contact;
|
||||
use App\Entity\Upload;
|
||||
use App\Entity\User;
|
||||
use App\Form\ContactType;
|
||||
use App\Model\AjaxModalResponseDto;
|
||||
use App\Service\Upload\UploadHandler;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
class EditController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UploadHandler $uploadHandler,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/admin/system/contact/edit/{id}', name: 'app_admin_system_contact_edit')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(Contact $contact, Request $request): JsonResponse
|
||||
{
|
||||
$response = new AjaxModalResponseDto();
|
||||
$formAction = $this->generateUrl('app_admin_system_contact_edit', ['id' => $contact->getId()]);
|
||||
// Handle upload independently from form submission to avoid issues with failing validation
|
||||
$uploadSession = $this->uploadHandler->getUploadSession();
|
||||
if (true === $request->isMethod('POST') && 0 < $uploadSession->getCount()) {
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$photo = Upload::fromUploadDto($uploadSession->getUploads()->first(), $user, Upload::TYPE_PHOTO);
|
||||
if (null !== $existingPhoto = $contact->getPhoto()) {
|
||||
$this->entityManager->remove($existingPhoto);
|
||||
}
|
||||
$contact->setPhoto($photo);
|
||||
$this->entityManager->flush();
|
||||
$this->uploadHandler->moveUploadSessionFilesFromOrphanage(Upload::TYPE_PHOTO, $uploadSession);
|
||||
$this->uploadHandler->destroyUploadSession();
|
||||
}
|
||||
|
||||
$form = $this->createForm(
|
||||
ContactType::class,
|
||||
$contact,
|
||||
[
|
||||
'action' => $formAction,
|
||||
'ajax_submit' => true,
|
||||
'upload_session' => $uploadSession,
|
||||
]
|
||||
);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->entityManager->flush();
|
||||
$this->addFlash('success', 'Der Ansprechpartner wurde aktualisiert');
|
||||
$this->logger->info('Edit contact', [
|
||||
'contact' => $contact->getName(),
|
||||
]);
|
||||
|
||||
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_contact_index'));
|
||||
} else {
|
||||
$response->setContent($this->renderView('admin/system/contact/edit.html.twig', [
|
||||
'form' => $form,
|
||||
]));
|
||||
}
|
||||
|
||||
return $this->json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin\System\Contact;
|
||||
|
||||
use App\Repository\ContactRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
class IndexController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly ContactRepository $contactRepository)
|
||||
{}
|
||||
|
||||
#[Route('/admin/system/contact', name: 'app_admin_system_contact_index')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(): Response
|
||||
{
|
||||
$contacts = $this
|
||||
->contactRepository
|
||||
->findBy([], ['name' => 'ASC'])
|
||||
;
|
||||
|
||||
return $this->render('admin/system/contact/index.html.twig', [
|
||||
'contacts' => $contacts,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,32 @@
|
||||
|
||||
namespace App\Controller\Teamer;
|
||||
|
||||
use App\Repository\ContactRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class ContactController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly ContactRepository $contactRepository)
|
||||
{}
|
||||
|
||||
#[Route('/teamer/contact', name: 'app_teamer_contact')]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('teamer/contact/index.html.twig');
|
||||
$generalContacts = $this
|
||||
->contactRepository
|
||||
->getGeneralContacts()
|
||||
;
|
||||
|
||||
$destinationContacts = $this
|
||||
->contactRepository
|
||||
->getDestinationContacts()
|
||||
;
|
||||
|
||||
return $this->render('teamer/contact/index.html.twig', [
|
||||
'generalContacts' => $generalContacts,
|
||||
'destinationContacts' => $destinationContacts,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\ContactRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ORM\Entity(repositoryClass: ContactRepository::class)]
|
||||
class Contact
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Assert\NotBlank(message: 'Bitte gib den Namen an')]
|
||||
private ?string $name = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Assert\NotBlank(message: 'Bitte gib die E-Mail-Adresse an')]
|
||||
#[Assert\Email(message: 'Bitte gib eine gültige E-Mail-Adresse an', mode: 'strict')]
|
||||
private ?string $email = null;
|
||||
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'], fetch: 'EAGER')]
|
||||
#[Assert\NotNull(message: 'Bitte lade ein Foto hoch')]
|
||||
private ?Upload $photo = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $destination = null;
|
||||
|
||||
#[ORM\OneToOne(mappedBy: 'contact', cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY')]
|
||||
private ?User $user = null;
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(string $email): static
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhoto(): ?Upload
|
||||
{
|
||||
return $this->photo;
|
||||
}
|
||||
|
||||
public function setPhoto(?Upload $photo): static
|
||||
{
|
||||
$this->photo = $photo;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDestination(): ?string
|
||||
{
|
||||
return $this->destination;
|
||||
}
|
||||
|
||||
public function setDestination(?string $destination): static
|
||||
{
|
||||
$this->destination = $destination;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(?User $user): static
|
||||
{
|
||||
// unset the owning side of the relation if necessary
|
||||
if ($user === null && $this->user !== null) {
|
||||
$this->user->setContact(null);
|
||||
}
|
||||
|
||||
// set the owning side of the relation if necessary
|
||||
if ($user !== null && $user->getContact() !== $this) {
|
||||
$user->setContact($this);
|
||||
}
|
||||
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class Teamer implements TimestampableEntityInterface
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Disposition::class, cascade: ['remove'])]
|
||||
private Collection $dispositions;
|
||||
|
||||
#[ORM\OneToOne(mappedBy: 'teamer')]
|
||||
#[ORM\OneToOne(mappedBy: 'teamer', fetch: 'EXTRA_LAZY')]
|
||||
private ?User $user = null;
|
||||
|
||||
#[ORM\Column]
|
||||
|
||||
@@ -45,6 +45,9 @@ class User implements UserInterface, TimestampableEntityInterface
|
||||
#[ORM\OneToOne(inversedBy: 'user', cascade: ['persist', 'remove'])]
|
||||
private ?Teamer $teamer = null;
|
||||
|
||||
#[ORM\OneToOne(inversedBy: 'user', cascade: ['persist', 'remove'])]
|
||||
private ?Contact $contact = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->uuid = Uuid::v4();
|
||||
@@ -200,4 +203,16 @@ class User implements UserInterface, TimestampableEntityInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContact(): ?Contact
|
||||
{
|
||||
return $this->contact;
|
||||
}
|
||||
|
||||
public function setContact(?Contact $contact): static
|
||||
{
|
||||
$this->contact = $contact;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Contact;
|
||||
use App\Model\UploadSessionDto;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ContactType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('name', TextType::class, [
|
||||
'label' => 'Name',
|
||||
])
|
||||
->add('email', EmailType::class, [
|
||||
'label' => 'E-Mail',
|
||||
])
|
||||
->add('destination', TextType::class, [
|
||||
'label' => 'Destination',
|
||||
'required' => false,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'data_class' => Contact::class,
|
||||
])
|
||||
->setRequired(['upload_session'])
|
||||
->setAllowedTypes('upload_session', UploadSessionDto::class)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,10 @@ class AdminMenuBuilder extends AbstractMenuBuilder
|
||||
'route' => 'app_admin_system_document_index',
|
||||
'title' => 'Dokumente',
|
||||
],
|
||||
[
|
||||
'route' => 'app_admin_system_contact_index',
|
||||
'title' => 'Ansprechpartner',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Contact;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Contact>
|
||||
*
|
||||
* @method Contact|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Contact|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Contact[] findAll()
|
||||
* @method Contact[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ContactRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Contact::class);
|
||||
}
|
||||
|
||||
public function getGeneralContacts(): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('contact');
|
||||
|
||||
return $qb
|
||||
->leftJoin('contact.photo', 'photo')
|
||||
->where($qb->expr()->isNull('contact.destination'))
|
||||
->orderBy('contact.name', 'ASC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
public function getDestinationContacts(): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('contact');
|
||||
|
||||
return $qb
|
||||
->leftJoin('contact.photo', 'photo')
|
||||
->where($qb->expr()->isNotNull('contact.destination'))
|
||||
->orderBy('contact.name', 'ASC')
|
||||
->addOrderBy('contact.destination', 'ASC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user