<?php
namespace App\Controller;
use App\Form\Auth\LoginFormType;
use App\Form\Auth\RegisterFormType;
use CustomerManagementFrameworkBundle\CustomerProvider\CustomerProviderInterface;
use Pimcore\Model\DataObject\Customer;
use Pimcore\Model\Document;
use Pimcore\Model\WebsiteSetting;
use App\Classes\Controller\AbstractFrontController as AbstractFrontController;
use App\Repository\CustomerRepository;
use App\Service\Contract\RecaptchaValidationServiceInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
class AuthenticationController extends AbstractFrontController
{
public function __construct(
protected CustomerRepository $customerRepository,
protected RecaptchaValidationServiceInterface $recaptchaValidationService,
protected TranslatorInterface $translator
){}
public function loginAction(Request $request, AuthenticationUtils $authenticationUtils)
{
$parameters['division'] = $request->get('division');
if ($this->isGranted('ROLE_USER')) {
return new RedirectResponse($request->get('_target_path') ?? '/' . $parameters['division']);
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$formData = [
'_username' => $lastUsername,
'_target_path' => $request->get('_target_path') ?? '/' . $parameters['division']
];
$form = $this->createForm(
LoginFormType::class,
$formData,
[
'action' => $this->generateUrl('login', $parameters),
]
);
return $this->render(
'@App/division/auth/login.html.twig',
[
'form' => $form->createView(),
'errorBag' => $request->getSession()->getFlashBag()->get('errors'),
'document' => Document::getByPath('/' . $parameters['division'])
]
);
}
public function registerAction(Request $request, CustomerProviderInterface $customerProvider)
{
$division = $request->get('division');
$selectedCountry = 'US';
$cache = new FilesystemAdapter();
$cachedCountryCode = $cache->getItem('country_code');
if (!$cachedCountryCode->isHit()) {
$accessKey = WebsiteSetting::getByName('geoLocationApiKey')->getData();
if (empty($accessKey)) {
$cachedCountryCode->set($selectedCountry)
->expiresAfter(3600 * 24 * 10); // 10 days
$cache->save($cachedCountryCode);
return;
}
// set IP address and API access key
$ip = $request->getClientIp();
// Initialize CURL:
$ch = curl_init('http://api.ipstack.com/'.$ip.'?access_key='.$accessKey.'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Store the data:
$json = curl_exec($ch);
curl_close($ch);
// Decode JSON response:
$apiResult = json_decode($json, true);
// Output the "capital" object inside "location"
if ($apiResult && !empty($apiResult['country_code'])) {
$selectedCountry = $apiResult['country_code'];
}
$cachedCountryCode->set($selectedCountry)
->expiresAfter(3600 * 24 * 10); // 10 days
$cache->save($cachedCountryCode);
}
$selectedCountry = $cachedCountryCode->get();
if ($this->isGranted('ROLE_USER')) {
return new RedirectResponse('/' . $division);
}
$form = $this->createForm(
RegisterFormType::class,
[
'accountInformation' => [
'divisions' => [strtolower(str_replace(' ', '-', $division))]
]
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
if (!$this->recaptchaValidationService->isValid($formData)) {
$this->addFlash('error', 'stoelting.recaptcha-failed.error');
return $this->redirectBack($request);
}
$userAlreadyExists = Customer::getByEmail($formData['accountInformation']['email'], 1);
if (!$userAlreadyExists) {
$backup = \Pimcore\Model\DataObject\AbstractObject::getHideUnpublished();
\Pimcore\Model\DataObject\AbstractObject::setHideUnpublished(false);
$unpublishedCustomer = Customer::getByEmail($formData['accountInformation']['email'])->current();
\Pimcore\Model\DataObject\AbstractObject::setHideUnpublished($backup);
if ($unpublishedCustomer && !empty(trim($unpublishedCustomer->getOldSiteRefId()))) {
$unpublishedCustomer->setSalt(null);
$customer = $this->customerRepository->fillCustomerData(
$formData,
$unpublishedCustomer
);
} else {
$customerInstance = $customerProvider->createCustomerInstance();
$customer = $this->customerRepository->fillCustomerData(
$formData,
$customerInstance
);
}
$this->addFlash(
'success',
$this->translator->trans('stoelting.user-successfully-registered')
);
$this->customerRepository->sendRegisteredEmail(
$customer,
[
'loginLink' => $this->generateUrl('login', ['division' => $division], UrlGeneratorInterface::ABSOLUTE_URL),
'loginLinkHref' => substr($this->generateUrl('login', ['division' => $division], UrlGeneratorInterface::NETWORK_PATH), 2)
]
);
return $this->redirectToRoute('login', ['division' => $division]);
}
$form->get('accountInformation')->get('email')->addError(
new FormError(
$this->translator->trans('stoelting.user-already-exists')
)
);
}
return $this->render(
'@App/division/auth/register.html.twig',
[
'form' => $form->createView(),
'selectedCountry' => $selectedCountry,
'document' => Document::getByPath('/' . $division)
]
);
}
public function logoutAction()
{
// controller can be blank: it will never be executed!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
function getRealIpAddr()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
}