Spaces:
No application file
No application file
namespace Mautic\CoreBundle\Controller; | |
use Symfony\Component\Form\ClickableInterface; | |
use Symfony\Component\Form\Form; | |
use Symfony\Component\Form\FormError; | |
use Symfony\Component\Form\FormInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
abstract class AbstractFormController extends CommonController | |
{ | |
protected ?string $permissionBase = null; | |
/** | |
* @return mixed | |
*/ | |
public function unlockAction(Request $request, $objectId, $objectModel) | |
{ | |
$model = $this->getModel($objectModel); | |
$entity = $model->getEntity($objectId); | |
$this->permissionBase = $model->getPermissionBase(); | |
if ($this->canEdit($entity)) { | |
if (null !== $entity && null !== $entity->getCheckedOutBy()) { | |
$model->unlockEntity($entity); | |
} | |
$returnUrl = urldecode($request->get('returnUrl')); | |
if (empty($returnUrl)) { | |
$returnUrl = $this->generateUrl('mautic_dashboard_index'); | |
} | |
$this->addFlashMessage( | |
'mautic.core.action.entity.unlocked', | |
[ | |
'%name%' => urldecode($request->get('name')), | |
] | |
); | |
return $this->redirect($returnUrl); | |
} | |
return $this->accessDenied(); | |
} | |
/** | |
* Returns view to index with a locked out message. | |
* | |
* @param array $postActionVars | |
* @param object $entity | |
* @param string $model | |
* @param bool $batch Flag if a batch action is being performed | |
* | |
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|array | |
*/ | |
protected function isLocked($postActionVars, $entity, $model, $batch = false) | |
{ | |
$date = $entity->getCheckedOut(); | |
$postActionVars = $this->refererPostActionVars($postActionVars); | |
$returnUrl = $postActionVars['returnUrl']; | |
$override = ''; | |
$modelClass = $this->getModel($model); | |
$nameFunction = $modelClass->getNameGetter(); | |
$this->permissionBase = $modelClass->getPermissionBase(); | |
if ($this->canEdit($entity)) { | |
$override = $this->translator->trans( | |
'mautic.core.override.lock', | |
[ | |
'%url%' => $this->generateUrl( | |
'mautic_core_form_action', | |
[ | |
'objectAction' => 'unlock', | |
'objectModel' => $model, | |
'objectId' => $entity->getId(), | |
'returnUrl' => $returnUrl, | |
'name' => urlencode($entity->$nameFunction()), | |
] | |
), | |
] | |
); | |
} | |
$flash = [ | |
'type' => 'error', | |
'msg' => 'mautic.core.error.locked', | |
'msgVars' => [ | |
'%name%' => $entity->$nameFunction(), | |
'%user%' => $entity->getCheckedOutByUser(), | |
'%contactUrl%' => $this->generateUrl( | |
'mautic_user_action', | |
[ | |
'objectAction' => 'contact', | |
'objectId' => $entity->getCheckedOutBy(), | |
'entity' => $model, | |
'id' => $entity->getId(), | |
'subject' => 'locked', | |
'returnUrl' => $returnUrl, | |
] | |
), | |
'%date%' => $date->format($this->coreParametersHelper->get('date_format_dateonly')), | |
'%time%' => $date->format($this->coreParametersHelper->get('date_format_timeonly')), | |
'%datetime%' => $date->format($this->coreParametersHelper->get('date_format_full')), | |
'%override%' => $override, | |
], | |
]; | |
if ($batch) { | |
return $flash; | |
} | |
return $this->postActionRedirect( | |
array_merge( | |
$postActionVars, | |
[ | |
'flashes' => [$flash], | |
] | |
) | |
); | |
} | |
/** | |
* Checks to see if the form was cancelled. | |
*/ | |
protected function isFormCancelled(FormInterface $form): bool | |
{ | |
$request = $this->getCurrentRequest(); | |
if (null === $request) { | |
throw new \RuntimeException('Request is required.'); | |
} | |
$formData = $request->request->get($form->getName()); | |
return is_array($formData) && array_key_exists('buttons', $formData) && array_key_exists('cancel', $formData['buttons']); | |
} | |
/** | |
* Checks to see if the form was applied or saved. | |
*/ | |
protected function isFormApplied(FormInterface $form): bool | |
{ | |
$request = $this->getCurrentRequest(); | |
if (null === $request) { | |
throw new \RuntimeException('Request is required.'); | |
} | |
$formData = $request->request->get($form->getName()); | |
return array_key_exists('buttons', $formData) && array_key_exists('apply', $formData['buttons']); | |
} | |
/** | |
* Binds form data, checks validity, and determines cancel request. | |
*/ | |
protected function isFormValid(FormInterface $form): bool | |
{ | |
$request = $this->getCurrentRequest(); | |
if (null === $request) { | |
throw new \RuntimeException('Request is required.'); | |
} | |
// bind request to the form | |
$form->handleRequest($request); | |
return $form->isSubmitted() && $form->isValid(); | |
} | |
/** | |
* Decide if current user can edit or can edit specific entity if entity is provided | |
* For BC, if permissionBase property is not set, it allow to edit only to administrators. | |
* | |
* @param object $entity | |
* | |
* @return bool | |
*/ | |
protected function canEdit($entity = null) | |
{ | |
if ($this->permissionBase) { | |
$permissionBase = $this->permissionBase; | |
} else { | |
$permissionBase = $this->getPermissionBase(); | |
} | |
if ($permissionBase) { | |
if ($entity && $this->security->checkPermissionExists($permissionBase.':editown')) { | |
return $this->security->hasEntityAccess( | |
$permissionBase.':editown', | |
$permissionBase.':editother', | |
$entity->getCreatedBy() | |
); | |
} elseif ($this->security->checkPermissionExists($permissionBase.':edit')) { | |
return $this->security->isGranted( | |
$permissionBase.':edit' | |
); | |
} | |
} | |
return $this->user->isAdmin(); | |
} | |
protected function copyErrorsRecursively(FormInterface $copyFrom, FormInterface $copyTo) | |
{ | |
/** @var FormError $error */ | |
foreach ($copyFrom->getErrors() as $error) { | |
$copyTo->addError($error); | |
} | |
foreach ($copyFrom->all() as $key => $child) { | |
if ($child instanceof Form && $copyTo->has($key)) { | |
$childTo = $copyTo->get($key); | |
$this->copyErrorsRecursively($child, $childTo); | |
} | |
} | |
} | |
/** | |
* generate $postActionVars with respect to available referer. | |
* | |
* @return array $postActionVars | |
*/ | |
protected function refererPostActionVars($vars) | |
{ | |
$request = $this->getCurrentRequest(); | |
if (null === $request) { | |
throw new \RuntimeException('Request is required.'); | |
} | |
if (empty($request->server->get('HTTP_REFERER'))) { | |
return $vars; | |
} | |
$returnUrl = !empty($request->server->get('HTTP_REFERER')) ? $request->server->get('HTTP_REFERER') : ''; | |
$vars['returnUrl'] = $returnUrl; | |
$urlMatcher = explode('/s/', $returnUrl); | |
$actionRoute = $this->get('router')->match('/s/'.$urlMatcher[1]); | |
$objAction = $actionRoute['objectAction'] ?? 'index'; | |
$routeCtrlr = explode('\\', $actionRoute['_controller']); | |
$defaultContentTemplate = $routeCtrlr[0].$routeCtrlr[1].':'.ucfirst(str_replace('Bundle', '', $routeCtrlr[1])).':'.$objAction; | |
$vars['contentTemplate'] ??= $defaultContentTemplate; | |
$vars['passthroughVars']['activeLink'] = '#'.str_replace('_action', '_'.$objAction, $actionRoute['_route']); | |
if (isset($actionRoute['objectId']) && $actionRoute['objectId'] > 0) { | |
$vars['viewParameters']['objectId'] = $actionRoute['objectId']; | |
} | |
return $vars; | |
} | |
protected function getFormButton(FormInterface $form, array $elements): ClickableInterface | |
{ | |
foreach ($elements as $element) { | |
$form = $form->get($element); | |
} | |
\assert($form instanceof ClickableInterface); | |
return $form; | |
} | |
} | |