<?php
namespace App\Controller\Account;
use App\Form\Type\CardType;
use App\Form\Type\CustomerImageType;
use CoreShop\Bundle\AddressBundle\Form\Type\AddressType;
use CoreShop\Bundle\CustomerBundle\Form\Type\CustomerType;
use CoreShop\Bundle\FrontendBundle\Controller\FrontendController;
use CoreShop\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use CoreShop\Component\Address\Model\Address;
use CoreShop\Component\Address\Model\AddressIdentifierInterface;
use CoreShop\Component\Address\Model\AddressInterface;
use CoreShop\Component\Address\Repository\CountryRepositoryInterface;
use CoreShop\Component\Core\Customer\Address\AddressAssignmentManagerInterface;
use CoreShop\Component\Core\Customer\Allocator\CustomerAddressAllocatorInterface;
use CoreShop\Component\Core\Model\CustomerInterface;
use CoreShop\Component\Customer\Context\CustomerContextInterface;
use CoreShop\Component\Order\Model\OrderInvoiceInterface;
use CoreShop\Component\Order\Renderer\OrderDocumentRendererInterface;
use CoreShop\Component\Order\Repository\OrderInvoiceRepositoryInterface;
use CoreShop\Component\Pimcore\DataObject\VersionHelper;
use Pimcore;
use Pimcore\Model\Asset;
use Pimcore\Model\Asset\Image;
use Pimcore\Model\DataObject\CoreShopOrder;
use Pimcore\Model\DataObject\Fieldcollection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class AccountController extends FrontendController
{
public CustomerAddressAllocatorInterface $customerAddressAllocator;
public function __construct(
public CountryRepositoryInterface $countryRepository,
private string $websiteUrl,
) {
$this->customerAddressAllocator = Pimcore::getContainer()->get(CustomerAddressAllocatorInterface::class);
}
public function informationsAction(Request $request): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_SETTINGS');
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirectToRoute('account_login');
}
$form = $this->get('form.factory')->createNamed('coreshop', CustomerType::class, $customer, [
'customer' => $customer->getId(),
'allow_default_address' => true,
]);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true)) {
$handledForm = $form->handleRequest($request);
if ($handledForm->isSubmitted() && $handledForm->isValid()) {
$customer = $handledForm->getData();
$customer->save();
$this->fireEvent($request, $customer, sprintf('%s.%s.%s_post', 'coreshop', 'customer', 'update'));
$this->addFlash('success', Pimcore::getContainer()->get('translator')->trans('coreshop.ui.customer.profile_successfully_updated'));
return $this->redirectToRoute('account_informations');
}
}
$customerImage = $customer->getImage();
$customerImage = $customerImage ? $customerImage->getFrontendFullPath() : false;
return $this->render('account/informations.html.twig', [
'customer' => $customer,
'profilePage' => true,
'customerImage'=>$customerImage,
'form' => $form->createView(),
]);
}
public function imageAction(Request $request): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_SETTINGS');
$customer = $this->getCustomer();
$form = $this->get('form.factory')->createNamed('coreshop', CustomerImageType::class, null);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true)) {
try {
$image = $request->files->get('coreshop')['Image'];
if(!$image || strpos($image->getMimeType(), 'image/') === false) {
throw new \Exception('Please upload valid image.');
} elseif($image->getSize() > 2097152) {
throw new \Exception('Image size should be less than 2MB.');
}
$getImage = $customer->getImage();
$fileName = "{$customer->getId()}_client_image.{$image->guessClientExtension()}";
//$getImage = Image::getByPath("/ClientImage/{$fileName}");
if(!$getImage) {
$getImage = new Image();
$getImage->setParent(Asset::getByPath('/ClientImage'));
$getImage->setData(file_get_contents($image->getRealPath()));
$getImage->setFilename($fileName);
$getImage->save();
$customer->setImage($getImage);
$customer->save();
} else {
$getImage->setData(file_get_contents($image->getRealPath()));
$versionCount = $getImage->getVersionCount();
$getImage->setFilename("{$versionCount}_{$fileName}");
$getImage->save();
}
$message = Pimcore::getContainer()->get('translator')->trans('coreshop.ui.customer.profile_successfully_updated');
return $this->json(['data' =>['url'=>$getImage->getFrontendFullPath()], 'message'=>$message, 'success' => true]);
} catch(\Exception $e) {
return $this->json(['data' =>[], 'message'=>$e->getMessage(), 'success' => false]);
}
}
return $this->render('account/informations/_image.html.twig', [
'customer' => $customer,
'form' => $form->createView(),
'display'=>$customer->getImage() ? 'none' : 'block',
]);
}
public function addressesAction(): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ADDRESSES');
$customer = $this->getCustomer();
// if(!$this->customerAddressAllocator->allocateForCustomer($customer)) {
// return $this->redirectToRoute('account_address_new');
// }
if (!$customer instanceof CustomerInterface) {
return $this->redirectToRoute('coreshop_index');
}
return $this->render('account/addresses_react.html.twig', [
'websiteUrl' => $this->websiteUrl,
]);
}
public function makeDefaultAddressAction(Request $request): Response
{
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirectToRoute('/');
}
$addressId = $this->getParameterFromRequest($request, 'address');
$customer->setDefaultAddress(Address::getById($addressId));
$customer->save();
$this->addFlash('success', Pimcore::getContainer()->get('translator')->trans(sprintf('coreshop.ui.customer.address_successfully_update')));
return $this->redirectToRoute('account_address');
}
public function addressAction(Request $request): Response
{
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirectToRoute('/');
}
//$nameUser = $customer->getFirstname()." ".$customer->getLastname();
$addressId = $this->getParameterFromRequest($request, 'address');
$address = Pimcore::getContainer()->get('coreshop.repository.address')->find($addressId);
if ($address instanceof AddressInterface) {
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ADDRESS_EDIT');
} else {
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ADDRESS_ADD');
}
$addressAssignmentManager = Pimcore::getContainer()->get(AddressAssignmentManagerInterface::class);
$eventType = 'update';
if (!$address instanceof AddressInterface) {
$eventType = 'add';
/** @var AddressInterface $address */
$address = Pimcore::getContainer()->get('coreshop.factory.address')->createNew();
$country = $this->countryRepository->findByCode('FR');
$address->setCountry($country);
$address->setFirstname($customer->getFirstname());
$address->setLastname($customer->getLastname());
if ($request->query->has('address_identifier')) {
$addressIdentifier = Pimcore::getContainer()->get('coreshop.repository.address_identifier')->findByName($request->query->get('address_identifier'));
if ($addressIdentifier instanceof AddressIdentifierInterface) {
//$address->setAddressIdentifier($addressIdentifier);
}
}
}
if ($eventType === 'update' && $addressAssignmentManager->checkAddressAffiliationPermissionForCustomer($customer, $address) === false) {
return $this->redirectToRoute('account_address');
}
$addressFormOptions = [
'available_affiliations' => $addressAssignmentManager->getAddressAffiliationTypesForCustomer($customer),
'selected_affiliation' => $addressAssignmentManager->detectAddressAffiliationForCustomer($customer, $address),
];
$form = $this->get('form.factory')->createNamed('coreshop', AddressType::class, $address, $addressFormOptions);
$form->handleRequest($request);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true)) {
$addressAffiliation = $form->has('addressAffiliation') ? $form->get('addressAffiliation')->getData() : null;
$addressAffiliation = null;
if ($form->isSubmitted()) {
$address = $form->getData();
// DEBUG FLORENT
/*
if($address->getCity() == "testes"){
var_dump($address->getStreet());
var_dump($address->getCity());
var_dump($form->isValid());
echo '<br/>';
var_dump($_POST);
$addressFormOptions = [
'available_affiliations' => $addressAssignmentManager->getAddressAffiliationTypesForCustomer($customer),
'selected_affiliation' => $addressAssignmentManager->detectAddressAffiliationForCustomer($customer, $address),
];
if (!$form->isValid()) {
$formErrors = $form->getErrors(true); // Récupération des erreurs du formulaire avec les noms de champs
$erreurs = [];
foreach ($formErrors as $error) {
// Accéder à l'origine de l'erreur pour obtenir le nom du champ associé
$fieldName = $error->getOrigin()->getName();
$errorMessage = $error->getMessage();
// Stocker le message d'erreur avec le nom du champ associé
$erreurs[] = [
'field' => $fieldName,
'message' => $errorMessage,
'data'=>$error->getOrigin()->getData(),
'cause'=>$error->getCause(),
];
}
// Affichage des erreurs avec les noms des champs
dump($erreurs);
//var_dump($addressFormOptions);
//die();
}
//die();
}
*/
if(! $form->isValid()) {
/*
$session = $request->getSession();
if ($session instanceof Session) {
$session->getFlashBag()->clear();
foreach ($form->getErrors(true) as $error) {
$session->getFlashBag()->add('error', $error->getOrigin()->getName(). ': '.$error->getMessage());
// var_dump($error->getOrigin()->getName(). ': '.$error->getMessage());
}
}*/
return $this->render('account/address/address.html.twig', [
'address' => $address,
'customer' => $customer,
'profilePage' => true,
'form' => $form->createView(),
]);
} else {
$address = $form->getData();
$address->setPublished(true);
$address->setKey(uniqid());
$address = $addressAssignmentManager->allocateAddressByAffiliation($customer, $address, $addressAffiliation);
$this->fireEvent($request, $address, sprintf('%s.%s.%s_post', 'coreshop', 'address', $eventType));
$this->addFlash('success', Pimcore::getContainer()->get('translator')->trans(sprintf('coreshop.ui.customer.address_successfully_%s', $eventType === 'add' ? 'added' : 'updated')));
if($eventType == 'add') {
$customer->setDefaultAddress($address);
$customer->save();
$customer->getDefaultAddress();
}
return $this->redirect(
$this->getParameterFromRequest($request, '_redirect', $this->generateUrl('account_address')),
);
}
}
}
return $this->render('account/address/address.html.twig', [
'address' => $address,
'customer' => $customer,
'profilePage' => true,
'form' => $form->createView(),
]);
}
public function addressDeleteAction(Request $request): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ADDRESS_DELETE');
$customer = $this->getCustomer();
$addressAssignmentManager = Pimcore::getContainer()->get(AddressAssignmentManagerInterface::class);
if (!$customer instanceof CustomerInterface) {
return $this->redirectToRoute('/');
}
$address = Pimcore::getContainer()->get('coreshop.repository.address')->find(
$this->getParameterFromRequest($request, 'address'),
);
if (!$address instanceof AddressInterface) {
return $this->redirectToRoute('account_address');
}
if ($addressAssignmentManager->checkAddressAffiliationPermissionForCustomer($customer, $address) === false) {
return $this->redirectToRoute('account_address');
}
$this->fireEvent($request, $address, sprintf('%s.%s.%s_pre', 'coreshop', 'address', 'delete'));
$address->delete();
$this->addFlash('success', Pimcore::getContainer()->get('translator')->trans('coreshop.ui.customer.address_successfully_deleted'));
return $this->redirectToRoute('account_address');
}
public function renderAction(Request $request): Response
{
$invoiceId = $this->getParameterFromRequest($request, 'id');
$invoice = $this->getOrderInvoiceRepository()->find($invoiceId);
if ($invoice instanceof OrderInvoiceInterface) {
try {
$responseData = $this->getOrderDocumentRenderer()->renderDocumentPdf($invoice);
$header = [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="invoice-' . $invoice->getId() . '.pdf"',
];
} catch (\Exception $e) {
$responseData = '<strong>' . $e->getMessage() . '</strong><br>trace: ' . $e->getTraceAsString();
$header = ['Content-Type' => 'text/html'];
}
return new Response($responseData, 200, $header);
}
throw new NotFoundHttpException(sprintf('Invoice with Id %s not found', $invoiceId));
}
public function headerAction(Request $request): Response
{
return $this->render('account/_header.html.twig', [
'customer' => $this->getCustomer(),
]);
//return $this->render('account/_headerwidget_react.html.twig', [
// 'websiteUrl' => $this->websiteUrl,
//]);
}
public function mediumPaymentAction(Request $request): Response
{
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirect('/');
}
return $this->render('account/medium_payment.html.twig', [
'customer' => $customer,
'profilePage' => true,
]);
}
public function mediumPaymentRemoveAction(Request $request): Response
{
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirect('/');
}
$items = $customer->getCardInformation();
$index = $this->getParameterFromRequest($request, 'index', null);
$items->remove($index);
$customer->setCardInformation($items);
$customer->save();
return $this->redirectToRoute('account_medium_payment');
}
public function mediumPaymentAddAction(Request $request): Response
{
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirect('/');
}
$card = new CardInfo();
$form = $this->get('form.factory')->createNamed('coreshop', CardType::class, $card);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true)) {
$data = $request->get('coreshop');
$card->setNameOnCard($data['NameOnCard']);
$card->setCardNumber($data['CardNumber']);
$card->setDate($data['Date']['month'].'/'.substr($data['Date']['year'], 2, 2));
$items = $customer->getCardInformation();
if(!$items) {
$items = new Fieldcollection();
}
$items->add($card);
$customer->setCardInformation($items);
$customer->save();
return $this->redirectToRoute('account_medium_payment');
}
return $this->render('account/payment/payment.html.twig', [
'customer' => $customer,
'profilePage' => true,
'form' => $form->createView()
]);
}
public function ordersAction(Request $request): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ORDERS');
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirect('/');
}
$orderListing = CoreShopOrder::getByCustomer(['id'=>$customer->getId(), 'type'=>'object']);
$orderListing->setCondition("saleState = 'order'");
$orderListing->setCondition("orderState in ('confirmed', 'complete')");
$orders = $orderListing->load();
return $this->render('account/orders.html.twig', [
'customer' => $customer,
'profilePage' => true,
'orders' => $orders,
]);
}
public function ordersTrackingAction(Request $request): Response
{
$this->denyAccessUnlessGranted('CORESHOP_CUSTOMER_PROFILE_ORDERS');
$orderId = $this->getParameterFromRequest($request, 'orderId', null);
$customer = $this->getCustomer();
if (!$customer instanceof CustomerInterface) {
return $this->redirect('/');
}
return $this->render('account/order_tracking.html.twig', [
'customer' => $customer,
'profilePage' => true,
'order' => CoreShopOrder::getById($orderId),
]);
}
public function confirmNewsletterAction(Request $request): Response
{
$success = false;
$token = $this->getParameterFromRequest($request, 'token');
$newsletterUser = null;
if (!$token) {
return $this->redirectToRoute('coreshop_index');
}
/**
* @var CustomerInterface $customer
*/
$customer = Pimcore::getContainer()->get('coreshop.repository.customer')->findByNewsletterToken($token);
if ($customer instanceof CustomerInterface) {
$customer->setNewsletterConfirmed(true);
$customer->setNewsletterToken(null);
VersionHelper::useVersioning(function () use ($customer) {
$customer->save();
}, false);
$this->fireEvent($request, $customer, sprintf('%s.%s.%s_post', 'coreshop', 'customer', 'newsletter_confirm'));
$this->addFlash('success', Pimcore::getContainer()->get('translator')->trans('coreshop.ui.newsletter_confirmed'));
$success = true;
} else {
$this->addFlash('error', Pimcore::getContainer()->get('translator')->trans('coreshop.ui.newsletter_confirmation_error'));
}
return $this->render('account/confirm_newsletter.html.twig', [
'newsletterUser' => $newsletterUser,
'success' => $success,
]);
}
public function listAction(Request $request): Response
{
return $this->render('account/list.html.twig');
}
public function noticeAction(Request $request): Response
{
return $this->render('account/notice.html.twig');
}
protected function getCustomer(): ?CustomerInterface
{
try {
/**
* @var CustomerInterface $customer
*/
$customer = Pimcore::getContainer()->get(CustomerContextInterface::class)->getCustomer();
return $customer;
} catch (\Exception) {
// fail silently
}
return null;
}
protected function fireEvent(Request $request, mixed $object, string $eventName): void
{
//@todo: move this to a resource controller event
$event = new ResourceControllerEvent($object, ['request' => $request]);
Pimcore::getContainer()->get('event_dispatcher')->dispatch($event, $eventName);
}
private function getOrderInvoiceRepository(): OrderInvoiceRepositoryInterface
{
return pimcore::getContainer()->get('coreshop.repository.order_invoice');
}
private function getOrderDocumentRenderer(): OrderDocumentRendererInterface
{
return pimcore::getContainer()->get('coreshop.renderer.order.pdf');
}
}