<?php
// src/App/Document/Areabrick/Iframe.php
namespace App\Document\Areabrick;
use Pimcore\Model\Document\Editable\Area\Info;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
class FormConfigurator extends AbstractAreabrick
{
protected $translator;
public function getName()
{
return 'form-configurator';
}
public function getDescription()
{
return 'Show form';
}
public function getTemplateLocation()
{
return static::TEMPLATE_LOCATION_GLOBAL;
}
public function getViewTemplate()
{
return 'areas/form-configurator/view.html.twig';
}
public function getEditTemplate()
{
return 'areas/form-configurator/edit.html.twig';
}
/**
* @inheritDoc
*/
public function hasEditTemplate()
{
return true;
}
// other methods defined above
//
public function action(Info $info)
{
$this->translator = $this->container->get('translator');
$formType = $info->getDocumentElement('form_type');
if (!$formType) {
return;
}
$class = $this->getFormClass($formType);
if (!$class) {
$info->setParam('error', 'Can not find form class for "'.$formType.'"');
return;
}
$data = [];
$options = [];
/** @var Form */
$form = $this->container->get('form.factory')->create($class, $data, $options);
if ($info->getRequest()->getMethod() == 'POST') {
$form->handleRequest($info->getRequest());
}
if ($form->isSubmitted() && $form->isValid()) {
$innerFormType = $form->getConfig()->getType()->getInnerType();
if (method_exists($innerFormType, 'persist') && is_callable([$innerFormType, 'persist'])) {
$status = false;
if (method_exists($innerFormType, 'getHasRecaptcha') && is_callable([$innerFormType, 'getHasRecaptcha'])) {
$hasRecaptcha = $innerFormType->getHasRecaptcha();
if ($hasRecaptcha) {
$data = $form->getData();
if (!$this->isValidRepatcha($data)) {
$this->addFlashMessage($info->getRequest(), 'error', 'stoelting.recaptcha-failed.error');
return $this->redirectBack($info->getRequest());
}
}
}
try {
$status = $innerFormType->persist($form, $info, $this);
} catch (\Exception $e) {
$this->addFlashMessage($info->getRequest(), 'error', $e->getMessage());
}
if ($status) {
$this->buildFlashMessage($info->getRequest(), 'success', $formType);
return $this->redirectBack($info->getRequest(), ['X-show-thankyou-page' => 'true']);
}
} else {
$this->addFlashMessage($info->getRequest(), 'error', 'stoelting.missing-form-handler.error');
}
}
$info->setParam('formTemplate', $this->getFormTemplate($formType));
$info->setParam('formObject', $form->createView());
}
protected function redirectBack(Request $request, array $headers = [])
{
$referer = $request->headers->get('referer', '/');
return new RedirectResponse($referer, 302, $headers);
}
protected function buildFlashMessage(Request $request, string $messageType, $formSlug)
{
$this->addFlashMessage($request, $messageType, 'stoelting.'.$formSlug.'.'.$messageType);
}
protected function addFlashMessage(Request $request, string $messageType, string $message)
{
$request->getSession()
->getFlashBag()
->add(
$messageType,
$this->translator->trans($message)
);
}
protected function isValidRepatcha(array $data)
{
$captcha = $data['g-recaptcha-response'];
$action = $data['action'];
$secret = $this->container->getParameter('recaptcha_v3_secret_key');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' => $secret, 'response' => $captcha)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$arrResponse = json_decode($response, true);
// verify the response
return ($arrResponse["success"] == true && $arrResponse["score"] >= 0.8 && $arrResponse['action'] == $action);
}
protected function getFormTemplate($name)
{
return 'Forms/FormConfigurator/'.$name.'.html.twig';
}
protected function getFormClass($name)
{
$classBaseName = implode('', array_map('ucfirst', array_values(array_filter(explode('-', $name)))));
$className = "\\App\\Form\\FormConfigurator\\{$classBaseName}";
if (!class_exists($className)) {
return false;
}
return $className;
}
}