chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
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\Form\Type\DateRangeType;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\ThemeHelper;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\CoreBundle\Model\AuditLogModel;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Service\FlashBag;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\CoreBundle\Twig\Helper\AnalyticsHelper;
use Mautic\CoreBundle\Twig\Helper\AssetsHelper;
use Mautic\CoreBundle\Twig\Helper\SlotsHelper;
use Mautic\FormBundle\Collector\AlreadyMappedFieldCollectorInterface;
use Mautic\FormBundle\Collector\MappedObjectCollector;
use Mautic\FormBundle\Entity\Field;
use Mautic\FormBundle\Entity\Form;
use Mautic\FormBundle\Exception\ValidationException;
use Mautic\FormBundle\Helper\FormFieldHelper;
use Mautic\FormBundle\Model\FormModel;
use Mautic\FormBundle\Model\SubmissionModel;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
class FormController extends CommonFormController
{
public function __construct(
FormFactoryInterface $formFactory,
FormFieldHelper $fieldHelper,
private AlreadyMappedFieldCollectorInterface $alreadyMappedFieldCollector,
private MappedObjectCollector $mappedObjectCollector,
ManagerRegistry $doctrine,
MauticFactory $factory,
ModelFactory $modelFactory,
UserHelper $userHelper,
CoreParametersHelper $coreParametersHelper,
EventDispatcherInterface $dispatcher,
Translator $translator,
FlashBag $flashBag,
RequestStack $requestStack,
CorePermissions $security
) {
parent::__construct($formFactory, $fieldHelper, $doctrine, $factory, $modelFactory, $userHelper, $coreParametersHelper, $dispatcher, $translator, $flashBag, $requestStack, $security);
}
/**
* @param int $page
*
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function indexAction(Request $request, PageHelperFactoryInterface $pageHelperFactory, $page = 1)
{
// set some permissions
$permissions = $this->security->isGranted(
[
'form:forms:viewown',
'form:forms:viewother',
'form:forms:create',
'form:forms:editown',
'form:forms:editother',
'form:forms:deleteown',
'form:forms:deleteother',
'form:forms:publishown',
'form:forms:publishother',
],
'RETURN_ARRAY'
);
if (!$permissions['form:forms:viewown'] && !$permissions['form:forms:viewother']) {
return $this->accessDenied();
}
$this->setListFilters();
$session = $request->getSession();
$pageHelper = $pageHelperFactory->make('mautic.form', $page);
$limit = $pageHelper->getLimit();
$start = $pageHelper->getStart();
$search = $request->get('search', $session->get('mautic.form.filter', ''));
$filter = ['string' => $search, 'force' => []];
$session->set('mautic.form.filter', $search);
if (!$permissions['form:forms:viewother']) {
$filter['force'][] = ['column' => 'f.createdBy', 'expr' => 'eq', 'value' => $this->user->getId()];
}
$orderBy = $session->get('mautic.form.orderby', 'f.dateModified');
$orderByDir = $session->get('mautic.form.orderbydir', $this->getDefaultOrderDirection());
$forms = $this->getModel('form.form')->getEntities(
[
'start' => $start,
'limit' => $limit,
'filter' => $filter,
'orderBy' => $orderBy,
'orderByDir' => $orderByDir,
]
);
$count = count($forms);
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_index', ['page' => $lastPage]);
return $this->postActionRedirect(
[
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $lastPage],
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
]
);
}
$pageHelper->rememberPage($page);
return $this->delegateView(
[
'viewParameters' => [
'searchValue' => $search,
'items' => $forms,
'totalItems' => $count,
'page' => $page,
'limit' => $limit,
'permissions' => $permissions,
'security' => $this->security,
'tmpl' => $request->get('tmpl', 'index'),
],
'contentTemplate' => '@MauticForm/Form/list.html.twig',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
'route' => $this->generateUrl('mautic_form_index', ['page' => $page]),
],
]
);
}
/**
* Loads a specific form into the detailed panel.
*
* @param int $objectId
*
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function viewAction(Request $request, $objectId)
{
/** @var FormModel $model */
$model = $this->getModel('form');
$activeForm = $model->getEntity($objectId);
// set the page we came from
$page = $request->getSession()->get('mautic.form.page', 1);
if (null === $activeForm) {
// set the return URL
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
return $this->postActionRedirect(
[
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $page],
'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',
$activeForm->getCreatedBy()
)
) {
return $this->accessDenied();
}
$permissions = $this->security->isGranted(
[
'form:forms:viewown',
'form:forms:viewother',
'form:forms:create',
'form:forms:editown',
'form:forms:editother',
'form:forms:deleteown',
'form:forms:deleteother',
'form:forms:publishown',
'form:forms:publishother',
],
'RETURN_ARRAY'
);
// Audit Log
$auditLogModel = $this->getModel('core.auditlog');
\assert($auditLogModel instanceof AuditLogModel);
$logs = $auditLogModel->getLogForObject('form', $objectId, $activeForm->getDateAdded());
// Init the date range filter form
$dateRangeValues = $request->get('daterange', []);
$action = $this->generateUrl('mautic_form_action', ['objectAction' => 'view', 'objectId' => $objectId]);
$dateRangeForm = $this->formFactory->create(DateRangeType::class, $dateRangeValues, ['action' => $action]);
$formSubmissionModel = $this->getModel('form.submission');
\assert($formSubmissionModel instanceof SubmissionModel);
// Submission stats per time period
$timeStats = $formSubmissionModel->getSubmissionsLineChartData(
null,
new \DateTime($dateRangeForm->get('date_from')->getData()),
new \DateTime($dateRangeForm->get('date_to')->getData()),
null,
['form_id' => $objectId]
);
// Only show actions and fields that still exist
$customComponents = $model->getCustomComponents();
$activeFormActions = [];
foreach ($activeForm->getActions() as $formAction) {
if (!isset($customComponents['actions'][$formAction->getType()])) {
continue;
}
$type = explode('.', $formAction->getType());
$activeFormActions[$type[0]][] = $formAction;
}
$activeFormFields = [];
$availableFields = array_flip($this->fieldHelper->getChoiceList($customComponents['fields']));
foreach ($activeForm->getFields() as $field) {
if (!isset($availableFields[$field->getType()])) {
continue;
}
$activeFormFields[] = $field;
}
$submissionCounts = $formSubmissionModel->getRepository()->getSubmissionCounts($activeForm);
return $this->delegateView(
[
'viewParameters' => [
'activeForm' => $activeForm,
'submissionCounts' => $submissionCounts,
'page' => $page,
'logs' => $logs,
'permissions' => $permissions,
'stats' => [
'submissionsInTime' => $timeStats,
],
'dateRangeForm' => $dateRangeForm->createView(),
'activeFormActions' => $activeFormActions,
'activeFormFields' => $activeFormFields,
'formScript' => htmlspecialchars($model->getFormScript($activeForm), ENT_QUOTES, 'UTF-8'),
'formContent' => htmlspecialchars($model->getContent($activeForm, false), ENT_QUOTES, 'UTF-8'),
'availableActions' => $customComponents['actions'],
],
'contentTemplate' => '@MauticForm/Form/details.html.twig',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
'route' => $action,
],
]
);
}
/**
* Generates new form and processes post data.
*
* @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
*
* @throws \Exception
*/
public function newAction(Request $request)
{
/** @var FormModel $model */
$model = $this->getModel('form');
$entity = $model->getEntity();
$session = $request->getSession();
if (!$this->security->isGranted('form:forms:create')) {
return $this->accessDenied();
}
// set the page we came from
$page = $request->getSession()->get('mautic.form.page', 1);
$mauticform = $request->request->get('mauticform') ?? [];
$sessionId = $mauticform['sessionId'] ?? 'mautic_'.sha1(uniqid(mt_rand(), true));
// set added/updated fields
$modifiedFields = $session->get('mautic.form.'.$sessionId.'.fields.modified', []);
$deletedFields = $session->get('mautic.form.'.$sessionId.'.fields.deleted', []);
// set added/updated actions
$modifiedActions = $session->get('mautic.form.'.$sessionId.'.actions.modified', []);
$deletedActions = $session->get('mautic.form.'.$sessionId.'.actions.deleted', []);
$action = $this->generateUrl('mautic_form_action', ['objectAction' => 'new']);
$form = $model->createForm($entity, $this->formFactory, $action);
// /Check for a submitted form and process it
if ('POST' == $request->getMethod()) {
$valid = false;
if (!$cancelled = $this->isFormCancelled($form)) {
if ($valid = $this->isFormValid($form)) {
// only save fields that are not to be deleted
$fields = array_diff_key($modifiedFields, array_flip($deletedFields));
// make sure that at least one field is selected
if (empty($fields)) {
// set the error
$form->addError(
new FormError(
$this->translator->trans('mautic.form.form.fields.notempty', [], 'validators')
)
);
$valid = false;
} else {
$model->setFields($entity, $fields);
try {
// Set alias to prevent SQL errors
$alias = $model->cleanAlias($entity->getName(), '', 10);
$entity->setAlias($alias);
// Set timestamps
$model->setTimestamps($entity, true, false);
// Save the form first and new actions so that new fields are available to actions.
// Using the repository function to not trigger the listeners twice.
$model->getRepository()->saveEntity($entity);
// Only save actions that are not to be deleted
$actions = array_diff_key($modifiedActions, array_flip($deletedActions));
// Set and persist actions
$model->setActions($entity, $actions);
// Save and trigger listeners
$model->saveEntity($entity, $this->getFormButton($form, ['buttons', 'save'])->isClicked());
$this->addFlashMessage(
'mautic.core.notice.created',
[
'%name%' => $entity->getName(),
'%menu_link%' => 'mautic_form_index',
'%url%' => $this->generateUrl(
'mautic_form_action',
[
'objectAction' => 'edit',
'objectId' => $entity->getId(),
]
),
]
);
if ($this->getFormButton($form, ['buttons', 'save'])->isClicked()) {
$viewParameters = [
'objectAction' => 'view',
'objectId' => $entity->getId(),
];
$returnUrl = $this->generateUrl('mautic_form_action', $viewParameters);
$template = 'Mautic\FormBundle\Controller\FormController::viewAction';
} else {
// return edit view so that all the session stuff is loaded
return $this->editAction($request, $entity->getId(), true);
}
} catch (ValidationException $ex) {
$form->addError(
new FormError(
$ex->getMessage()
)
);
$valid = false;
} catch (\Exception $e) {
$form['name']->addError(
new FormError($this->translator->trans('mautic.form.schema.failed', [], 'validators'))
);
$valid = false;
if ('dev' == $this->getParameter('kernel.environment')) {
throw $e;
}
}
}
}
} else {
$viewParameters = ['page' => $page];
$returnUrl = $this->generateUrl('mautic_form_index', $viewParameters);
$template = 'Mautic\FormBundle\Controller\FormController::indexAction';
}
if ($cancelled || ($valid && $this->getFormButton($form, ['buttons', 'save'])->isClicked())) {
// clear temporary fields
$this->clearSessionComponents($request, $sessionId);
return $this->postActionRedirect(
[
'returnUrl' => $returnUrl,
'viewParameters' => $viewParameters,
'contentTemplate' => $template,
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
]
);
}
} else {
// clear out existing fields in case the form was refreshed, browser closed, etc
$this->clearSessionComponents($request, $sessionId);
$modifiedFields = $modifiedActions = $deletedActions = $deletedFields = [];
$form->get('sessionId')->setData($sessionId);
// add a submit button
$keyId = 'new'.hash('sha1', uniqid(mt_rand()));
$field = new Field();
$modifiedFields[$keyId] = $field->convertToArray();
$modifiedFields[$keyId]['label'] = $this->translator->trans('mautic.core.form.submit');
$modifiedFields[$keyId]['alias'] = 'submit';
$modifiedFields[$keyId]['showLabel'] = 1;
$modifiedFields[$keyId]['type'] = 'button';
$modifiedFields[$keyId]['id'] = $keyId;
$modifiedFields[$keyId]['inputAttributes'] = 'class="btn btn-default"';
$modifiedFields[$keyId]['formId'] = $sessionId;
unset($modifiedFields[$keyId]['form']);
$session->set('mautic.form.'.$sessionId.'.fields.modified', $modifiedFields);
}
// fire the form builder event
$customComponents = $model->getCustomComponents();
return $this->delegateView(
[
'viewParameters' => [
'fields' => $this->fieldHelper->getChoiceList($customComponents['fields']),
'formFields' => $modifiedFields,
'mappedFields' => $this->mappedObjectCollector->buildCollection(...$entity->getMappedFieldObjects()),
'deletedFields' => $deletedFields,
'viewOnlyFields' => $customComponents['viewOnlyFields'],
'actions' => $customComponents['choices'],
'actionSettings' => $customComponents['actions'],
'formActions' => $modifiedActions,
'deletedActions' => $deletedActions,
'tmpl' => $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index',
'activeForm' => $entity,
'form' => $form->createView(),
'inBuilder' => true,
],
'contentTemplate' => '@MauticForm/Builder/index.html.twig',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
'route' => $this->generateUrl(
'mautic_form_action',
[
'objectAction' => (!empty($valid) ? 'edit' : 'new'), // valid means a new form was applied
'objectId' => $entity->getId(),
]
),
],
]
);
}
/**
* Generates edit form and processes post data.
*
* @param int|Form $objectId
* @param bool $ignorePost
* @param bool $forceTypeSelection
*
* @return \Symfony\Component\HttpFoundation\JsonResponse|Response
*/
public function editAction(Request $request, $objectId, $ignorePost = false, $forceTypeSelection = false)
{
/** @var FormModel $model */
$model = $this->getModel('form');
$formData = $request->request->get('mauticform');
$sessionId = $formData['sessionId'] ?? null;
$customComponents = $model->getCustomComponents();
$modifiedFields = [];
$deletedFields = [];
$modifiedActions = [];
$deletedActions = [];
if ($objectId instanceof Form) {
$entity = $objectId;
$objectId = 'mautic_'.sha1(uniqid(mt_rand(), true));
} else {
$entity = $model->getEntity($objectId);
// Process submit of cloned form
if (null == $entity && $objectId == $sessionId) {
$entity = $model->getEntity();
}
}
$session = $request->getSession();
$cleanSlate = true;
// set the page we came from
$page = $request->getSession()->get('mautic.form.page', 1);
// set the return URL
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
$postActionVars = [
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $page],
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
];
// form not found
if (null === $entity) {
return $this->postActionRedirect(
array_merge(
$postActionVars,
[
'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();
} elseif ($model->isLocked($entity)) {
// deny access if the entity is locked
return $this->isLocked($postActionVars, $entity, 'form.form');
}
$action = $this->generateUrl('mautic_form_action', ['objectAction' => 'edit', 'objectId' => $objectId]);
$form = $model->createForm($entity, $this->formFactory, $action);
// /Check for a submitted form and process it
if (!$ignorePost && 'POST' == $request->getMethod()) {
$valid = false;
if (!$cancelled = $this->isFormCancelled($form)) {
// set added/updated fields
$modifiedFields = $session->get('mautic.form.'.$objectId.'.fields.modified', []);
$deletedFields = $session->get('mautic.form.'.$objectId.'.fields.deleted', []);
$fields = array_diff_key($modifiedFields, array_flip($deletedFields));
// set added/updated actions
$modifiedActions = $session->get('mautic.form.'.$objectId.'.actions.modified', []);
$deletedActions = $session->get('mautic.form.'.$objectId.'.actions.deleted', []);
$actions = array_diff_key($modifiedActions, array_flip($deletedActions));
if ($valid = $this->isFormValid($form)) {
// make sure that at least one field is selected
if (empty($fields)) {
// set the error
$form->addError(
new FormError(
$this->translator->trans('mautic.form.form.fields.notempty', [], 'validators')
)
);
$valid = false;
} else {
$model->setFields($entity, $fields);
$model->deleteFields($entity, $deletedFields);
$alias = $entity->getAlias();
if (empty($alias)) {
$alias = $model->cleanAlias($entity->getName(), '', 10);
$entity->setAlias($alias);
}
if (!$entity->getId()) {
// Set timestamps because this is a new clone
$model->setTimestamps($entity, true, false);
}
// save the form first so that new fields are available to actions
// use the repository method to not trigger listeners twice
try {
$model->getRepository()->saveEntity($entity);
// Ensure actions are compatible with form type
if (!$entity->isStandalone()) {
foreach ($actions as $actionId => $action) {
if (empty($customComponents['actions'][$action['type']]['allowCampaignForm'])) {
unset($actions[$actionId]);
$deletedActions[] = $actionId;
}
}
}
if (count($actions)) {
// Now set and persist the actions
$model->setActions($entity, $actions);
}
// Delete deleted actions
$model->deleteActions($entity, $deletedActions);
// Persist and execute listeners
$model->saveEntity($entity, $this->getFormButton($form, ['buttons', 'save'])->isClicked());
// Reset objectId to entity ID (can be session ID in case of cloned entity)
$objectId = $entity->getId();
$this->addFlashMessage(
'mautic.core.notice.updated',
[
'%name%' => $entity->getName(),
'%menu_link%' => 'mautic_form_index',
'%url%' => $this->generateUrl(
'mautic_form_action',
[
'objectAction' => 'edit',
'objectId' => $entity->getId(),
]
),
]
);
if ($this->getFormButton($form, ['buttons', 'save'])->isClicked()) {
$viewParameters = [
'objectAction' => 'view',
'objectId' => $entity->getId(),
];
$returnUrl = $this->generateUrl('mautic_form_action', $viewParameters);
$template = 'Mautic\FormBundle\Controller\FormController::viewAction';
}
} catch (ValidationException $ex) {
$form->addError(
new FormError(
$ex->getMessage()
)
);
$valid = false;
}
}
}
} else {
// unlock the entity
$model->unlockEntity($entity);
$viewParameters = ['page' => $page];
$returnUrl = $this->generateUrl('mautic_form_index', $viewParameters);
$template = 'Mautic\FormBundle\Controller\FormController::indexAction';
}
if ($cancelled || ($valid && $this->getFormButton($form, ['buttons', 'save'])->isClicked())) {
// remove fields from session
$this->clearSessionComponents($request, $objectId);
// Clear session items in case columns changed
$session->remove('mautic.formresult.'.$entity->getId().'.orderby');
$session->remove('mautic.formresult.'.$entity->getId().'.orderbydir');
$session->remove('mautic.formresult.'.$entity->getId().'.filters');
return $this->postActionRedirect(
array_merge(
$postActionVars,
[
'returnUrl' => $returnUrl,
'viewParameters' => $viewParameters,
'contentTemplate' => $template,
]
)
);
} elseif ($valid && $form->get('buttons')->get('apply')->isClicked()) {
// Rebuild everything to include new ids
$cleanSlate = true;
$reorder = true;
if ($valid) {
// Rebuild the form with new action so that apply doesn't keep creating a clone
$action = $this->generateUrl('mautic_form_action', ['objectAction' => 'edit', 'objectId' => $entity->getId()]);
$form = $model->createForm($entity, $this->formFactory, $action);
}
}
} else {
$cleanSlate = true;
// lock the entity
$model->lockEntity($entity);
}
if (!$form->isSubmitted()) {
$form->get('sessionId')->setData($objectId);
}
// Get field and action settings
$availableFields = $this->fieldHelper->getChoiceList($customComponents['fields']);
if ($cleanSlate) {
// clean slate
$this->clearSessionComponents($request, $objectId);
$this->alreadyMappedFieldCollector->removeAllForForm($objectId);
// load existing fields into session
$modifiedFields = [];
$existingFields = $entity->getFields()->toArray();
$submitButton = false;
foreach ($existingFields as $formField) {
// Check to see if the field still exists
if ('button' == $formField->getType()) {
// submit button found
$submitButton = true;
}
if ('button' !== $formField->getType() && !in_array($formField->getType(), $availableFields)) {
continue;
}
$id = $formField->getId();
$field = $formField->convertToArray();
if (!$id) {
// Cloned entity
$id = $field['id'] = $field['sessionId'] = 'new'.hash('sha1', uniqid(mt_rand()));
}
unset($field['form']);
if (isset($customComponents['fields'][$field['type']])) {
// Set the custom parameters
$field['customParameters'] = $customComponents['fields'][$field['type']];
}
$field['formId'] = $objectId;
$modifiedFields[$id] = $field;
if (!empty($field['mappedObject']) && !empty($field['mappedField']) && empty($field['parent'])) {
$this->alreadyMappedFieldCollector->addField($objectId, $field['mappedObject'], $field['mappedField']);
}
}
if (!$submitButton) { // means something deleted the submit button from the form
// add a submit button
$keyId = 'new'.hash('sha1', uniqid(mt_rand()));
$field = new Field();
$modifiedFields[$keyId] = $field->convertToArray();
$modifiedFields[$keyId]['label'] = $this->translator->trans('mautic.core.form.submit');
$modifiedFields[$keyId]['alias'] = 'submit';
$modifiedFields[$keyId]['showLabel'] = 1;
$modifiedFields[$keyId]['type'] = 'button';
$modifiedFields[$keyId]['id'] = $keyId;
$modifiedFields[$keyId]['inputAttributes'] = 'class="btn btn-default"';
$modifiedFields[$keyId]['formId'] = $objectId;
unset($modifiedFields[$keyId]['form']);
}
if (!empty($reorder)) {
uasort(
$modifiedFields,
fn ($a, $b): int => $a['order'] <=> $b['order']
);
}
$session->set('mautic.form.'.$objectId.'.fields.modified', $modifiedFields);
$deletedFields = [];
// Load existing actions into session
$modifiedActions = [];
$existingActions = $entity->getActions()->toArray();
foreach ($existingActions as $formAction) {
// Check to see if the action still exists
if (!isset($customComponents['actions'][$formAction->getType()])) {
continue;
}
$id = $formAction->getId();
$action = $formAction->convertToArray();
if (!$id) {
// Cloned entity so use a random Id instead
$action['id'] = $id = 'new'.hash('sha1', uniqid(mt_rand()));
}
unset($action['form']);
$modifiedActions[$id] = $action;
}
if (!empty($reorder)) {
uasort(
$modifiedActions,
fn ($a, $b): int => $a['order'] <=> $b['order']
);
}
$session->set('mautic.form.'.$objectId.'.actions.modified', $modifiedActions);
$deletedActions = [];
}
return $this->delegateView(
[
'viewParameters' => [
'fields' => $availableFields,
'formFields' => $modifiedFields,
'deletedFields' => $deletedFields,
'mappedFields' => $this->mappedObjectCollector->buildCollection(...$entity->getMappedFieldObjects()),
'formActions' => $modifiedActions,
'deletedActions' => $deletedActions,
'viewOnlyFields' => $customComponents['viewOnlyFields'],
'actions' => $customComponents['choices'],
'actionSettings' => $customComponents['actions'],
'fieldSettings' => $customComponents['fields'],
'tmpl' => $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index',
'activeForm' => $entity,
'form' => $form->createView(),
'forceTypeSelection' => $forceTypeSelection,
'inBuilder' => true,
],
'contentTemplate' => '@MauticForm/Builder/index.html.twig',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
'route' => $this->generateUrl(
'mautic_form_action',
[
'objectAction' => 'edit',
'objectId' => $entity->getId(),
]
),
],
]
);
}
/**
* Clone an entity.
*
* @param int $objectId
*
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function cloneAction(Request $request, $objectId)
{
$model = $this->getModel('form.form');
/** @var Form $entity */
$entity = $model->getEntity($objectId);
if (null != $entity) {
if (!$this->security->isGranted('form:forms:create')
|| !$this->security->hasEntityAccess(
'form:forms:viewown',
'form:forms:viewother',
$entity->getCreatedBy()
)
) {
return $this->accessDenied();
}
$entity = clone $entity;
$entity->setIsPublished(false);
// Clone the forms's fields
$fields = $entity->getFields()->toArray();
/** @var Field $field */
foreach ($fields as $field) {
$fieldClone = clone $field;
$fieldClone->setForm($entity);
$fieldClone->setSessionId(null);
$entity->addField($field->getId(), $fieldClone);
}
// Clone the forms's actions
$actions = $entity->getActions()->toArray();
/** @var \Mautic\FormBundle\Entity\Action $action */
foreach ($actions as $action) {
$actionClone = clone $action;
$actionClone->setForm($entity);
$entity->addAction($action->getId(), $actionClone);
}
}
return $this->editAction($request, $entity, true, true);
}
/**
* Gives a preview of the form.
*
* @param int $objectId
*/
public function previewAction($objectId, ThemeHelper $themeHelper, AssetsHelper $assetsHelper, SlotsHelper $slotsHelper, AnalyticsHelper $analyticsHelper): Response
{
/** @var FormModel $model */
$model = $this->getModel('form.form');
$form = $model->getEntity($objectId);
if (null === $form) {
$html =
'<h1>'.
$this->translator->trans('mautic.form.error.notfound', ['%id%' => $objectId], 'flashes').
'</h1>';
} elseif (!$this->security->hasEntityAccess(
'form:forms:editown',
'form:forms:editother',
$form->getCreatedBy()
)
) {
$html = '<h1>'.$this->translator->trans('mautic.core.error.accessdenied', [], 'flashes').'</h1>';
} else {
$html = $model->getContent($form, true, false);
}
$model->populateValuesWithGetParameters($form, $html);
$viewParams = [
'content' => $html,
'stylesheets' => [],
'name' => $form->getName(),
'metaRobots' => '<meta name="robots" content="index">',
];
if ($form->getNoIndex()) {
$viewParams['metaRobots'] = '<meta name="robots" content="noindex">';
}
// Use form specific template or system-wide default theme
$template = $form->getTemplate() ?? $this->coreParametersHelper->get('theme');
if (!empty($template)) {
$theme = $themeHelper->getTheme($template);
if ($theme->getTheme() != $template) {
$config = $theme->getConfig();
if (in_array('form', $config['features'])) {
$template = $theme->getTheme();
} else {
$template = null;
}
}
}
$viewParams['template'] = $template;
if (!empty($template)) {
$logicalName = $themeHelper->checkForTwigTemplate('@themes/'.$template.'/html/form.html.twig');
$slotsHelper->set('pageTitle', $form->getName());
$analytics = $analyticsHelper->getCode();
if (!empty($analytics)) {
$assetsHelper->addCustomDeclaration($analytics);
}
if ($form->getNoIndex()) {
$assetsHelper->addCustomDeclaration('<meta name="robots" content="noindex">');
}
return $this->render($logicalName, $viewParams);
}
return $this->render('@MauticForm/form.html.twig', $viewParams);
}
/**
* Deletes the entity.
*
* @param int $objectId
*
* @return Response
*/
public function deleteAction(Request $request, $objectId)
{
$page = $request->getSession()->get('mautic.form.page', 1);
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
$flashes = [];
$postActionVars = [
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $page],
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
];
if (Request::METHOD_POST === $request->getMethod()) {
$model = $this->getModel('form.form');
\assert($model instanceof FormModel);
$entity = $model->getEntity($objectId);
if (null === $entity) {
$flashes[] = [
'type' => 'error',
'msg' => 'mautic.form.error.notfound',
'msgVars' => ['%id%' => $objectId],
];
} elseif (!$this->security->hasEntityAccess(
'form:forms:deleteown',
'form:forms:deleteother',
$entity->getCreatedBy()
)
) {
return $this->accessDenied();
} elseif ($model->isLocked($entity)) {
return $this->isLocked($postActionVars, $entity, 'form.form');
}
$model->deleteEntity($entity);
$identifier = $this->translator->trans($entity->getName());
$flashes[] = [
'type' => 'notice',
'msg' => 'mautic.core.notice.deleted',
'msgVars' => [
'%name%' => $identifier,
'%id%' => $objectId,
],
];
} // else don't do anything
return $this->postActionRedirect(
array_merge(
$postActionVars,
[
'flashes' => $flashes,
]
)
);
}
/**
* Deletes a group of entities.
*
* @return Response
*/
public function batchDeleteAction(Request $request)
{
$page = $request->getSession()->get('mautic.form.page', 1);
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
$flashes = [];
$postActionVars = [
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $page],
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
];
if (Request::METHOD_POST === $request->getMethod()) {
$model = $this->getModel('form');
\assert($model instanceof FormModel);
$ids = json_decode($request->query->get('ids', ''));
$deleteIds = [];
// Loop over the IDs to perform access checks pre-delete
foreach ($ids as $objectId) {
$objectId = (int) $objectId;
$entity = $model->getEntity($objectId);
if (null === $entity) {
$flashes[] = [
'type' => 'error',
'msg' => 'mautic.form.error.notfound',
'msgVars' => ['%id%' => $objectId],
];
} elseif (!$this->security->hasEntityAccess(
'form:forms:deleteown',
'form:forms:deleteother',
$entity->getCreatedBy()
)
) {
$flashes[] = $this->accessDenied(true);
} elseif ($model->isLocked($entity)) {
$flashes[] = $this->isLocked($postActionVars, $entity, 'form.form', true);
} else {
$deleteIds[] = $objectId;
}
}
// Delete everything we are able to
if (!empty($deleteIds)) {
$entities = $model->deleteEntities($deleteIds);
$flashes[] = [
'type' => 'notice',
'msg' => 'mautic.form.notice.batch_deleted',
'msgVars' => [
'%count%' => count($entities),
],
];
}
} // else don't do anything
return $this->postActionRedirect(
array_merge(
$postActionVars,
[
'flashes' => $flashes,
]
)
);
}
/**
* Clear field and actions from the session.
*/
public function clearSessionComponents(Request $request, $sessionId): void
{
$session = $request->getSession();
$session->remove('mautic.form.'.$sessionId.'.fields.modified');
$session->remove('mautic.form.'.$sessionId.'.fields.deleted');
$session->remove('mautic.form.'.$sessionId.'.actions.modified');
$session->remove('mautic.form.'.$sessionId.'.actions.deleted');
$this->alreadyMappedFieldCollector->removeAllForForm((string) $sessionId);
}
public function batchRebuildHtmlAction(Request $request)
{
$page = $request->getSession()->get('mautic.form.page', 1);
$returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
$flashes = [];
$postActionVars = [
'returnUrl' => $returnUrl,
'viewParameters' => ['page' => $page],
'contentTemplate' => 'Mautic\FormBundle\Controller\FormController::indexAction',
'passthroughVars' => [
'activeLink' => '#mautic_form_index',
'mauticContent' => 'form',
],
];
if ('POST' == $request->getMethod()) {
/** @var FormModel $model */
$model = $this->getModel('form');
$ids = json_decode($request->query->get('ids', ''));
$count = 0;
// Loop over the IDs to perform access checks pre-delete
foreach ($ids as $objectId) {
$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()
)
) {
$flashes[] = $this->accessDenied(true);
} elseif ($model->isLocked($entity)) {
$flashes[] = $this->isLocked($postActionVars, $entity, 'form.form', true);
} else {
$model->generateHtml($entity);
++$count;
}
}
$flashes[] = [
'type' => 'notice',
'msg' => 'mautic.form.notice.batch_html_generated',
'msgVars' => [
'%count%' => $count,
],
];
} // else don't do anything
return $this->postActionRedirect(
array_merge(
$postActionVars,
[
'flashes' => $flashes,
]
)
);
}
public function getModelName(): string
{
return 'form';
}
protected function getDefaultOrderDirection(): string
{
return 'DESC';
}
}