<?php
namespace App\Controller;
use App\Dto\ContactFormData;
use App\Form\ContactForm;
use App\Security\ApiUser;
use App\Service\Client\ActivityFeedService;
use App\Service\Client\Content\VideoListingService;
use App\Service\Client\MailService;
use App\Service\Client\User\AccountService;
use App\Service\Client\User\AmateurListingService;
use App\Service\Client\User\MemberService;
use App\Service\ReCaptchaService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class HomeController extends AbstractController
{
protected VideoListingService $videoService;
protected AmateurListingService $amateurService;
protected ActivityFeedService $activityService;
protected AccountService $accountService;
public function __construct(VideoListingService $service, AmateurListingService $amateurService, ActivityFeedService $activityService, AccountService $accountService)
{
$this->videoService = $service;
$this->amateurService = $amateurService;
$this->activityService = $activityService;
$this->accountService = $accountService;
}
/**
* @Route("/")
* @Route("/infostream")
* @Template()
* @return array
*/
public function index(\Redis $redis): array
{
/** @var ?ApiUser $user */
$user = $this->getUser();
$feedHtmls = ['initial' => [], 'delayed' => []];
if (null === $user) {
# gitlab #593
#$feedHtmls = $this->activityService->getPublicInfostream($redis);
}
return [
'videos' => $this->videoService->getBestOfTheMonthVideos(1, 6),
'onlineAmateurs' => $this->amateurService->getTopRatedAmateurs(1, 30, true, true),
'otherAmateurs' => $this->amateurService->getRandomAmateurs(6, true),
'feedHtmls' => $feedHtmls
];
}
/**
* @Route("/contact/privacy")
* @Template()
* @return array
*/
public function privacy(): array
{
return [];
}
/**
* @Route("/contact/terms")
* @Template()
* @return array
*/
public function terms(): array
{
return [];
}
/**
* @Route("/contact/about")
* @Template()
* @return array
*/
public function about(): array
{
return [];
}
/**
* @Route("/kontakt")
* @Template()
* @return array|Response
*/
public function contact(Request $request, MemberService $memberService, MailService $mailService, ReCaptchaService $recaptchaService, FlashBagInterface $flashBag)
{
$user = $this->getUser();
$userDetails = [];
if ($user instanceof ApiUser && $user->getUsername() !== '') {
$userDetails = $memberService->getMemberDetailByUsername($user->getUsername());
}
$form = $this->createForm(ContactForm::class, (new ContactFormData($userDetails)));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (!$recaptchaService->isValidSubmission($request)) {
$flashBag->add('info', 'Bitte lösen Sie das Captcha.');
return new RedirectResponse($this->generateUrl('app_home_contact'));
}
$form->getData()->setIsUserLoggedIn(false);
try {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$form->getData()->setIsUserLoggedIn(true);
} catch (AccessDeniedException $a) {
}
// Some sanity checks to battle spam
$doSend = $this->doesContainSpam($form->getData()) === false;
if($doSend === true) {
if ($mailService->sendContactInquiry($form->getData())) {
$request->getSession()->set('emailSent', true);
$request->getSession()->set('failure', false);
} else {
$request->getSession()->set('emailSent', false);
$request->getSession()->set('failure', true);
}
} else {
// if spam is detacted we don't send an email but don't want to alarm anybody, so stay silent!
$request->getSession()->set('emailSent', true);
$request->getSession()->set('failure', false);
}
return new RedirectResponse($this->generateUrl('app_home_contact'));
}
$emailSent = $request->getSession()->remove('emailSent') ?? false;
$failure = $request->getSession()->remove('failure') ?? false;
return [
'form' => $form->createView(),
'emailSent' => $emailSent,
'failure' => $failure,
];
}
/**
* @Route("/password-change/confirm/{confirmationToken}")
* @param string $confirmationToken
* @return RedirectResponse
* @throws \Psr\Cache\InvalidArgumentException
* @throws \ReflectionException
*/
public function passwordChangeConfirm(string $confirmationToken): RedirectResponse
{
try {
if ($this->accountService->changePasswordConfirmation($confirmationToken)) {
return $this->redirectToRoute('app_security_logout');
}
$this->addFlash('warning', 'Der verwendete Link ist evtl. nicht mehr gültig. Bitte versuche es erneut oder kontaktiere den Support.');
} catch (\DomainException $e) {
$this->addFlash('error', $e->getMessage());
}
if ($this->getUser() instanceof ApiUser) {
return $this->redirectToRoute('app_user_dashboard_index');
}
return $this->redirectToRoute('login');
}
/**
* @Route("/email-change/confirm/{confirmationToken}")
* @param string $confirmationToken
* @return RedirectResponse
*/
public function emailChangeConfirm(string $confirmationToken): RedirectResponse
{
try {
if ($this->accountService->changeEmailConfirmation($confirmationToken)) {
return $this->redirectToRoute('app_security_logout');
}
$this->addFlash('warning', 'Der verwendete Link ist evtl. nicht mehr gültig. Bitte versuche es erneut oder kontaktiere den Support.');
} catch (\DomainException $e) {
$this->addFlash('error', $e->getMessage());
}
if ($this->getUser() instanceof ApiUser) {
return $this->redirectToRoute('app_user_dashboard_index');
}
return $this->redirectToRoute('login');
}
/**
* Checks if the given $text contains any link
*
* @param string $text text to search in
* @return bool
*/
private function doesStringContainLink(string $text): bool {
return (bool)preg_match("/http[s]?:\/\//", $text);
}
/**
* Checks some values to determine if contact request is valid (length checks, link checks)
*
* @param ContactFormData $data data to check
* @return bool is the request fishy and shall be processed as spam?
*/
private function doesContainSpam(ContactFormData $data) {
$dataAsArr = $data->toArray();
foreach(array_keys($dataAsArr) as $key) {
if(in_array($key, ["message"]) === false && strlen($dataAsArr[$key]) > 0 && $this->doesStringContainLink($dataAsArr[$key]) === true) {
// links are only allowed in the message field
return true;
}
}
if(strlen($data->getFirstName()) > 50) {
// firstName exceeding 50 chars? Seams fishy -> bye bye
return true;
}
if(strlen($data->getLastName()) > 50) {
// lastName exceeding 50 chars? Seams fishy -> bye bye
return true;
}
if(strlen($data->getEmail()) > 100 || filter_var($data->getEmail(), FILTER_VALIDATE_EMAIL) === false) {
// mail exceeding 100 chars? Seams fishy -> bye bye
return true;
}
return false;
}
}