Spaces:
No application file
No application file
namespace Mautic\FormBundle\Controller; | |
use Doctrine\Persistence\ManagerRegistry; | |
use Mautic\CoreBundle\Controller\FormController as CommonFormController; | |
use Mautic\CoreBundle\Factory\MauticFactory; | |
use Mautic\CoreBundle\Factory\ModelFactory; | |
use Mautic\CoreBundle\Factory\PageHelperFactoryInterface; | |
use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
use Mautic\CoreBundle\Helper\UserHelper; | |
use Mautic\CoreBundle\Security\Permissions\CorePermissions; | |
use Mautic\CoreBundle\Service\FlashBag; | |
use Mautic\CoreBundle\Translation\Translator; | |
use Mautic\FormBundle\Helper\FormFieldHelper; | |
use Mautic\FormBundle\Helper\FormUploader; | |
use Mautic\FormBundle\Model\FieldModel; | |
use Mautic\FormBundle\Model\FormModel; | |
use Mautic\FormBundle\Model\SubmissionModel; | |
use Mautic\FormBundle\Model\SubmissionResultLoader; | |
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
use Symfony\Component\Filesystem\Filesystem; | |
use Symfony\Component\Form\FormFactoryInterface; | |
use Symfony\Component\HttpFoundation\BinaryFileResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\RequestStack; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpFoundation\ResponseHeaderBag; | |
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
class ResultController extends CommonFormController | |
{ | |
public function __construct(FormFactoryInterface $formFactory, FormFieldHelper $fieldHelper, ManagerRegistry $doctrine, MauticFactory $factory, ModelFactory $modelFactory, UserHelper $userHelper, CoreParametersHelper $coreParametersHelper, EventDispatcherInterface $dispatcher, Translator $translator, FlashBag $flashBag, RequestStack $requestStack, CorePermissions $security) | |
{ | |
$this->setStandardParameters( | |
'form.submission', // model name | |
'form:forms', // permission base | |
'mautic_form', // route base | |
'mautic.formresult', // session base | |
'mautic.form.result', // lang string base | |
'@MauticForm/Result', // template base | |
'mautic_form', // activeLink | |
'formresult' // mauticContent | |
); | |
parent::__construct($formFactory, $fieldHelper, $doctrine, $factory, $modelFactory, $userHelper, $coreParametersHelper, $dispatcher, $translator, $flashBag, $requestStack, $security); | |
} | |
/** | |
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response | |
*/ | |
public function indexAction(Request $request, PageHelperFactoryInterface $pageHelperFacotry, int $objectId, int $page = 1) | |
{ | |
/** @var FormModel $formModel */ | |
$formModel = $this->getModel('form.form'); | |
$form = $formModel->getEntity($objectId); | |
$session = $request->getSession(); | |
$formPage = $session->get('mautic.form.page', 1); | |
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $formPage]); | |
$viewOnlyFields = $formModel->getCustomComponents()['viewOnlyFields']; | |
if (null === $form) { | |
// redirect back to form list | |
return $this->postActionRedirect( | |
[ | |
'returnUrl' => $returnUrl, | |
'viewParameters' => ['page' => $formPage], | |
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction', | |
'passthroughVars' => [ | |
'activeLink' => 'mautic_form_index', | |
'mauticContent' => 'form', | |
], | |
'flashes' => [ | |
[ | |
'type' => 'error', | |
'msg' => 'mautic.form.error.notfound', | |
'msgVars' => ['%id%' => $objectId], | |
], | |
], | |
] | |
); | |
} elseif (!$this->security->hasEntityAccess( | |
'form:forms:viewown', | |
'form:forms:viewother', | |
$form->getCreatedBy() | |
) | |
) { | |
return $this->accessDenied(); | |
} | |
if ('POST' === $request->getMethod()) { | |
$this->setListFilters($request->query->get('name')); | |
} | |
$pageHelper = $pageHelperFacotry->make('mautic.formresult.'.$objectId, $page); | |
// set limits | |
$limit = $pageHelper->getLimit(); | |
$start = $pageHelper->getStart(); | |
// Set order direction to desc if not set | |
if (!$session->get('mautic.formresult.'.$objectId.'.orderbydir', null)) { | |
$session->set('mautic.formresult.'.$objectId.'.orderbydir', 'DESC'); | |
} | |
$orderBy = $session->get('mautic.formresult.'.$objectId.'.orderby', 's.date_submitted'); | |
$orderByDir = $session->get('mautic.formresult.'.$objectId.'.orderbydir', 'DESC'); | |
$filters = $session->get('mautic.formresult.'.$objectId.'.filters', []); | |
$model = $this->getModel('form.submission'); | |
if ($request->query->has('result')) { | |
// Force ID | |
$filters['s.id'] = ['column' => 's.id', 'expr' => 'like', 'value' => (int) $request->query->get('result'), 'strict' => false]; | |
$session->set("mautic.formresult.$objectId.filters", $filters); | |
} | |
// get the results | |
$entities = $model->getEntities( | |
[ | |
'start' => $start, | |
'limit' => $limit, | |
'filter' => ['force' => $filters], | |
'orderBy' => $orderBy, | |
'orderByDir' => $orderByDir, | |
'form' => $form, | |
'withTotalCount' => true, | |
'viewOnlyFields' => $viewOnlyFields, | |
'simpleResults' => true, | |
] | |
); | |
$count = $entities['count']; | |
$results = $entities['results']; | |
unset($entities); | |
if ($count && $count < ($start + 1)) { | |
// the number of entities are now less then the current page so redirect to the last page | |
$lastPage = $pageHelper->countPage($count); | |
$pageHelper->rememberPage($lastPage); | |
$returnUrl = $this->generateUrl('mautic_form_results', ['objectId' => $objectId, 'page' => $lastPage]); | |
return $this->postActionRedirect( | |
[ | |
'returnUrl' => $returnUrl, | |
'viewParameters' => ['page' => $lastPage], | |
'contentTemplate' => 'Mautic\FormBundle\Controller\ResultController::indexAction', | |
'passthroughVars' => [ | |
'activeLink' => 'mautic_form_index', | |
'mauticContent' => 'formresult', | |
], | |
] | |
); | |
} | |
// set what page currently on so that we can return here if need be | |
$pageHelper->rememberPage($page); | |
return $this->delegateView( | |
[ | |
'viewParameters' => [ | |
'items' => $results, | |
'filters' => $filters, | |
'form' => $form, | |
'viewOnlyFields' => $viewOnlyFields, | |
'page' => $page, | |
'totalCount' => $count, | |
'limit' => $limit, | |
'tmpl' => $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index', | |
'canDelete' => $this->security->hasEntityAccess( | |
'form:forms:editown', | |
'form:forms:editother', | |
$form->getCreatedBy() | |
), | |
'enableExportPermission'=> $this->security->isAdmin() || $this->security->isGranted('form:export:enable', 'MATCH_ONE'), | |
], | |
'contentTemplate' => '@MauticForm/Result/list.html.twig', | |
'passthroughVars' => [ | |
'activeLink' => 'mautic_form_index', | |
'mauticContent' => 'formresult', | |
'route' => $this->generateUrl( | |
'mautic_form_results', | |
[ | |
'objectId' => $objectId, | |
'page' => $page, | |
] | |
), | |
], | |
] | |
); | |
} | |
/** | |
* @return BinaryFileResponse | |
*/ | |
public function downloadFileAction(int $submissionId, string $field, FormUploader $formUploader) | |
{ | |
/** @var SubmissionResultLoader $submissionResultLoader */ | |
$submissionResultLoader = $this->getModel('form.submission_result_loader'); | |
$submission = $submissionResultLoader->getSubmissionWithResult($submissionId); | |
if (!$submission) { | |
throw $this->createNotFoundException(); | |
} | |
$results = $submission->getResults(); | |
$fieldEntity = $submission->getFieldByAlias($field); | |
if (empty($results[$field]) || null === $fieldEntity) { | |
throw $this->createNotFoundException(); | |
} | |
if (empty($fieldEntity->getProperties()['public']) && !$this->security->hasEntityAccess( | |
'form:forms:viewown', | |
'form:forms:viewother', | |
$submission->getForm()->getCreatedBy()) | |
) { | |
return $this->accessDenied(); | |
} | |
$fileName = $results[$field]; | |
$file = $formUploader->getCompleteFilePath($fieldEntity, $fileName); | |
$fs = new Filesystem(); | |
if (!$fs->exists($file)) { | |
throw $this->createNotFoundException(); | |
} | |
$response = new BinaryFileResponse($file); | |
$response::trustXSendfileTypeHeader(); | |
$response->setContentDisposition( | |
ResponseHeaderBag::DISPOSITION_ATTACHMENT, | |
$fileName | |
); | |
return $response; | |
} | |
public function downloadFileByFileNameAction(string $fieldId, string $fileName, FieldModel $fieldModel, FormUploader $formUploader): Response | |
{ | |
$fieldEntity = $fieldModel->getEntity($fieldId); | |
if (empty($fieldEntity->getProperties()['public']) && !$this->security->hasEntityAccess( | |
'form:forms:viewown', | |
'form:forms:viewother', | |
$fieldEntity->getForm()->getCreatedBy()) | |
) { | |
return $this->accessDenied(); | |
} | |
$file = $formUploader->getCompleteFilePath($fieldEntity, $fileName); | |
$fs = new Filesystem(); | |
if (!$fs->exists($file)) { | |
throw $this->createNotFoundException(); | |
} | |
$response = new BinaryFileResponse($file); | |
$response::trustXSendfileTypeHeader(); | |
$response->setContentDisposition( | |
ResponseHeaderBag::DISPOSITION_ATTACHMENT, | |
$fileName | |
); | |
return $response; | |
} | |
/** | |
* @param int $objectId | |
* @param string $format | |
* | |
* @return Response | |
* | |
* @throws \Exception | |
*/ | |
public function exportAction(Request $request, $objectId, $format = 'csv') | |
{ | |
$formModel = $this->getModel('form.form'); | |
$form = $formModel->getEntity($objectId); | |
$session = $request->getSession(); | |
$formPage = $session->get('mautic.form.page', 1); | |
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $formPage]); | |
if (!$this->security->isAdmin() && !$this->security->isGranted('form:export:enable', 'MATCH_ONE')) { | |
return $this->accessDenied(); | |
} | |
if (null === $form) { | |
// redirect back to form list | |
return $this->postActionRedirect( | |
[ | |
'returnUrl' => $returnUrl, | |
'viewParameters' => ['page' => $formPage], | |
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction', | |
'passthroughVars' => [ | |
'activeLink' => 'mautic_form_index', | |
'mauticContent' => 'form', | |
], | |
'flashes' => [ | |
[ | |
'type' => 'error', | |
'msg' => 'mautic.form.error.notfound', | |
'msgVars' => ['%id%' => $objectId], | |
], | |
], | |
] | |
); | |
} elseif (!$this->security->hasEntityAccess( | |
'form:forms:viewown', | |
'form:forms:viewother', | |
$form->getCreatedBy() | |
) | |
) { | |
return $this->accessDenied(); | |
} | |
$orderBy = $session->get('mautic.formresult.'.$objectId.'.orderby', 's.date_submitted'); | |
$orderByDir = $session->get('mautic.formresult.'.$objectId.'.orderbydir', 'DESC'); | |
$filters = $session->get('mautic.formresult.'.$objectId.'.filters', []); | |
$args = [ | |
'limit' => false, | |
'filter' => ['force' => $filters], | |
'orderBy' => $orderBy, | |
'orderByDir' => $orderByDir, | |
'form' => $form, | |
]; | |
/** @var SubmissionModel $model */ | |
$model = $this->getModel('form.submission'); | |
return $model->exportResults($format, $form, $args); | |
} | |
/** | |
* Delete a form result. | |
* | |
* @return array|Response | |
*/ | |
public function deleteAction(Request $request) | |
{ | |
$formId = $request->get('formId', 0); | |
$objectId = $request->get('objectId', 0); | |
$session = $request->getSession(); | |
$page = $session->get('mautic.formresult.'.$formId.'.page', 1); | |
$flashes = []; | |
if (Request::METHOD_POST === $request->getMethod()) { | |
$model = $this->getModel('form.submission'); | |
\assert($model instanceof SubmissionModel); | |
// Find the result | |
$entity = $model->getEntity($objectId); | |
if (null === $entity) { | |
$flashes[] = [ | |
'type' => 'error', | |
'msg' => 'mautic.form.error.notfound', | |
'msgVars' => ['%id%' => $objectId], | |
]; | |
} elseif (!$this->security->hasEntityAccess('form:forms:editown', 'form:forms:editother', $entity->getCreatedBy())) { | |
return $this->accessDenied(); | |
} else { | |
$id = $entity->getId(); | |
$model->deleteEntity($entity); | |
$flashes[] = [ | |
'type' => 'notice', | |
'msg' => 'mautic.core.notice.deleted', | |
'msgVars' => [ | |
'%name%' => '#'.$id, | |
], | |
]; | |
} | |
} // else don't do anything | |
$viewParameters = [ | |
'objectId' => $formId, | |
'page' => $page, | |
]; | |
return $this->postActionRedirect( | |
[ | |
'returnUrl' => $this->generateUrl('mautic_form_results', $viewParameters), | |
'viewParameters' => $viewParameters, | |
'contentTemplate' => 'Mautic\FormBundle\Controller\ResultController::indexAction', | |
'passthroughVars' => [ | |
'mauticContent' => 'formresult', | |
], | |
'flashes' => $flashes, | |
] | |
); | |
} | |
/** | |
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse | |
*/ | |
public function batchDeleteAction(Request $request) | |
{ | |
return $this->batchDeleteStandard($request); | |
} | |
protected function getModelName(): string | |
{ | |
return 'form.submission'; | |
} | |
protected function getIndexRoute(): string | |
{ | |
return 'mautic_form_results'; | |
} | |
protected function getActionRoute(): string | |
{ | |
return 'mautic_form_results_action'; | |
} | |
/** | |
* Set the main form ID as the objectId. | |
*/ | |
protected function generateUrl(string $route, array $parameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string | |
{ | |
$formId = $this->getFormIdFromRequest($parameters); | |
switch ($route) { | |
case 'mautic_form_results_action': | |
$parameters['formId'] = $formId; | |
break; | |
case 'mautic_form_results': | |
$parameters['objectId'] = $formId; | |
break; | |
} | |
return parent::generateUrl($route, $parameters, $referenceType); | |
} | |
public function getPostActionRedirectArguments(array $args, $action): array | |
{ | |
switch ($action) { | |
case 'batchDelete': | |
$formId = $this->getFormIdFromRequest(); | |
$args['viewParameters']['objectId'] = $formId; | |
break; | |
} | |
return $args; | |
} | |
/** | |
* @param array $parameters | |
* | |
* @return mixed | |
*/ | |
protected function getFormIdFromRequest($parameters = []) | |
{ | |
$request = $this->getCurrentRequest(); | |
if ($request->attributes->has('formId')) { | |
$formId = $request->attributes->get('formId'); | |
} elseif ($request->request->has('formId')) { | |
$formId = $request->request->get('formId'); | |
} else { | |
$objectId = $parameters['objectId'] ?? 0; | |
$formId = $parameters['formId'] ?? $request->query->get('formId', $objectId); | |
} | |
return $formId; | |
} | |
} | |